ฉันต้องการแทรกช่องว่าง 'n' (หรือสตริงใด ๆ ) ที่จุดเริ่มต้นของสตริงใน C ++ มีวิธีโดยตรงในการดำเนินการโดยใช้ std :: strings หรือ char * strings หรือไม่
เช่นใน Python คุณสามารถทำได้
>>> "." * 5 + "lolcat"
'.....lolcat'
ฉันต้องการแทรกช่องว่าง 'n' (หรือสตริงใด ๆ ) ที่จุดเริ่มต้นของสตริงใน C ++ มีวิธีโดยตรงในการดำเนินการโดยใช้ std :: strings หรือ char * strings หรือไม่
เช่นใน Python คุณสามารถทำได้
>>> "." * 5 + "lolcat"
'.....lolcat'
คำตอบ:
ในกรณีเฉพาะของการซ้ำอักขระเดี่ยวคุณสามารถใช้std::string(size_type count, CharT ch)
:
std::string(5, '.') + "lolcat"
NB ไม่สามารถใช้เพื่อทำซ้ำสตริงหลายอักขระ
ไม่มีวิธีสำนวนโดยตรงในการทำซ้ำสตริงใน C ++ เทียบเท่ากับตัวดำเนินการ*ใน Python หรือตัวดำเนินการxใน Perl หากคุณทำซ้ำอักขระเดียวตัวสร้างสองอาร์กิวเมนต์ (ตามที่คำตอบก่อนหน้านี้แนะนำ) จะทำงานได้ดี:
std::string(5, '.')
นี่คือตัวอย่างที่สร้างขึ้นของวิธีที่คุณอาจใช้ ostringstream เพื่อทำซ้ำสตริง n ครั้ง:
#include <sstream>
std::string repeat(int n) {
std::ostringstream os;
for(int i = 0; i < n; i++)
os << "repeat";
return os.str();
}
อาจมีประสิทธิภาพมากกว่าการต่อสตริง n ครั้งทั้งนี้ขึ้นอยู่กับการนำไปใช้งาน
ใช้หนึ่งในรูปแบบของ string :: insert:
std::string str("lolcat");
str.insert(0, 5, '.');
สิ่งนี้จะแทรก "..... " (ห้าจุด) ที่จุดเริ่มต้นของสตริง (ตำแหน่ง 0)
ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันก็อยากทำแบบเดียวกันและพบว่าสิ่งที่ฉันคิดว่าเป็นวิธีแก้ปัญหาที่ง่ายกว่า ดูเหมือนว่า cout มีฟังก์ชันนี้ในตัว cout.fill () โปรดดูลิงค์สำหรับคำอธิบาย "ฉบับเต็ม"
http://www.java-samples.com/showtutorial.php?tutorialid=458
cout.width(11);
cout.fill('.');
cout << "lolcat" << endl;
เอาท์พุท
.....lolcat
cout << "" << endl;
สำหรับวัตถุประสงค์ของตัวอย่างที่มีให้โดย OP ที่มาตรฐาน :: ctor std::string(5, '.')
สตริงจะเพียงพอที่: อย่างไรก็ตามหากใครกำลังมองหาฟังก์ชันที่จะทำซ้ำ std :: string หลาย ๆ ครั้ง:
std::string repeat(const std::string& input, unsigned num)
{
std::string ret;
ret.reserve(input.size() * num);
while (num--)
ret += input;
return ret;
}
ดังที่พลเรือจัตวา Jaeger กล่าวพาดพิงฉันไม่คิดว่าคำตอบอื่นใดจะตอบคำถามนี้ได้จริง คำถามถามว่าจะทำอย่างไรให้สตริงซ้ำไม่ใช่อักขระ
แม้ว่าคำตอบของพลเรือจัตวาจะถูกต้อง แต่ก็ไม่มีประสิทธิภาพ นี่คือการใช้งานที่เร็วขึ้นแนวคิดคือการลดการคัดลอกการดำเนินการและการจัดสรรหน่วยความจำโดยการเพิ่มสตริงแบบทวีคูณก่อน:
#include <string>
#include <cstddef>
std::string repeat(std::string str, const std::size_t n)
{
if (n == 0) {
str.clear();
str.shrink_to_fit();
return str;
} else if (n == 1 || str.empty()) {
return str;
}
const auto period = str.size();
if (period == 1) {
str.append(n - 1, str.front());
return str;
}
str.reserve(period * n);
std::size_t m {2};
for (; m < n; m *= 2) str += str;
str.append(str.c_str(), (n - (m / 2)) * period);
return str;
}
นอกจากนี้เรายังสามารถกำหนด an operator*
เพื่อให้ใกล้เคียงกับเวอร์ชัน Python มากขึ้น:
#include <utility>
std::string operator*(std::string str, std::size_t n)
{
return repeat(std::move(str), n);
}
บนเครื่องของฉันเร็วกว่าการใช้งานของ Commodore ประมาณ 10 เท่าและเร็วกว่าโซลูชัน'ผนวก n - 1 เท่า' ที่ไร้เดียงสาประมาณ 2 เท่า
+=
ภายในสำหรับลูปของคุณภายในยังมีการวนซ้ำบางประเภทที่str.size()
ทำซ้ำ str.size()
เพิ่มขึ้นในการวนซ้ำรอบนอกแต่ละครั้งดังนั้นหลังจากการวนซ้ำรอบนอกแต่ละครั้งวงในจะต้องทำซ้ำมากขึ้น การใช้งาน 'copy n times' ของคุณและไร้เดียงสาโดยรวมทั้งn * period
อักขระสำเนา reserve
การดำเนินงานของคุณไม่จัดสรรหน่วยความจำเพียงหนึ่งเพราะการเริ่มต้น ผมคิดว่าคุณประวัติการดำเนินงานของคุณด้วยค่อนข้างเล็กstr
และขนาดใหญ่n
แต่ไม่ได้ยังมีขนาดใหญ่และขนาดเล็กstr
n
str
และเล็กn
ระหว่างสองแนวทางนี้ ฉันเชื่อว่านี่เป็นสิ่งที่เกี่ยวข้องกับไปป์ไลน์โดยรวมมากกว่าการคาดการณ์รายสาขานอกจากนี้ยังมีประเด็นการจัดตำแหน่งข้อมูลที่ต้องพิจารณา คุณควรถามคำถามใหม่สำหรับรายละเอียดว่าเหตุใดจึงเป็นมิตรกับโปรเซสเซอร์ / หน่วยความจำมากกว่าฉันแน่ใจว่ามันจะได้รับความสนใจเป็นอย่างมากและได้รับคำตอบที่ดีกว่าที่ฉันจะให้ได้
rep movsb
เป็นวิธีการคัดลอกที่มีประสิทธิภาพมากที่สุดวิธีหนึ่งอย่างน้อยสำหรับสำเนาขนาดกลางถึงขนาดใหญ่ การดำเนินงานไมโครรหัสมันมีอะไรบางอย่างที่อยู่ใกล้คงที่ค่าใช้จ่ายในการเริ่มต้น (ทั้ง AMD และ Intel) เช่นในแซนดีบริดจ์, ~ 15-40 รอบบวก 4 รอบต่อสายแคช 64B (กรณีที่ดีที่สุด) สำหรับสำเนาขนาดเล็ก SSE loop จะดีที่สุดเนื่องจากไม่มีค่าใช้จ่ายในการเริ่มต้นระบบ แต่มันขึ้นอยู่กับการคาดเดาผิดสาขา
ITNOA
คุณสามารถใช้ฟังก์ชัน C ++ เพื่อทำสิ่งนี้
std::string repeat(const std::string& input, size_t num)
{
std::ostringstream os;
std::fill_n(std::ostream_iterator<std::string>(os), num, input);
return os.str();
}