2008-10-03 2 views
75

C++의 문자열 시작 부분에 'n'공백 (또는 임의의 문자열)을 삽입하고 싶습니다. std :: strings 또는 char * 문자열을 사용하여이 작업을 수행하는 직접적인 방법이 있습니까?C++에서 문자열을 여러 번 반복하는 방법은 무엇입니까?

예. 파이썬에서 당신은 단순히 std::string's constructors

>>> "." * 5 + "lolcat" 
'.....lolcat' 
+0

누군가 QString을 사용하여 답변을 제공합니까? – Akiva

+1

정말 답을 받아 들여야합니다. – starbeamrainbowlabs

답변

118
std::string foo = std::string(5, '.') + "lolcat"; 

체크 아웃 할 수 있습니다.

+26

OP는 문자가 아닌 문자열 반복을 요구했습니다. –

18

사용 캐릭터 : 삽입의 형태 중 하나

std::string str("lolcat"); 
str.insert(0, 5, '.'); 

이 "....."삽입합니다 (다섯 점) 문자열 (위치 0)의 시작.

+0

OP는 문자가 아닌 문자열 반복을 요구했습니다. – Brent

+0

@Brent OP는 둘 다 - " 'n 개의 공백 (또는 임의의 문자열)"을 물어 본 다음 단일 기간을 문자열로 사용하여 의도를 입증합니다. 영어는 많은 사람들의 모국어가 아니기 때문에 때로는 정확한 요구 사항을 추측 할 필요가 있으며 분석 할 때 질문은 실제로 한 사람의 성격으로 어떻게해야하는지 묻습니다. 내 대답을 찾지 못해 미안 하네. – camh

28

은 C에서 문자열을 반복 직접 관용적 방법 ++ 파이썬에서 * 운영자 또는 펄에서 X 연산자와 같습니다 없습니다. 단일 문자를 반복하는 경우 (이전 답변에 의해 제안) 2 개의 인수를 생성자는 잘 작동 :

std::string(5, '.') 

이 당신이 문자열을 n 번 반복하는 ostringstream을 사용하는 방법의 인위적인 예입니다 :

#include <sstream> 

std::string repeat(int n) { 
    std::ostringstream os; 
    for(int i = 0; i < n; i++) 
     os << "repeat"; 
    return os.str(); 
} 

구현에 따라 간단히 문자열을 n 번 연결하는 것보다 약간 더 효율적일 수 있습니다.

9

나는 이것이 이전 질문이지만, 똑같은 일을하기를 원했고, 더 간단한 해결책이라고 생각하는 것을 발견했다. COUT이 cout.fill (에 내장 된이 기능) 제독 저격병는 언급으로,

http://www.java-samples.com/showtutorial.php?tutorialid=458

cout.width(11); 
cout.fill('.'); 
cout << "lolcat" << endl; 

출력

.....lolcat 
+1

원한다면 원하는 모든 점이 작동하지 않습니다. – uckelman

+4

점만 : 마지막 줄을 ...로 변경하십시오. "cout <<" "<< endl; – musefan

4

는 '전체'에 대한 설명은 링크를 참조 것으로 보인다 , 난 다른 대답 중 하나가 실제로이 질문에 대답 생각하지 않는다; 질문은 문자가 아닌 문자열을 반복하는 방법을 묻습니다.

코모도어의 답이 맞지만 매우 비효율적입니다.여기에 빠른 구현이며, 아이디어가 처음 기하 급수적으로 증가 문자열에 의해 운영 및 메모리 할당을 복사 최소화하는 것입니다 :

#include <utility> 

std::string operator*(std::string str, std::size_t n) 
{ 
    return repeat(std::move(str), n); 
} 
:

#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; 
} 

우리는 또한 파이썬 버전에 가까운 무언가를 얻기 위해 operator*를 정의 할 수 있습니다

내 컴퓨터에서 이것은 Commodore에서 제공 한 구현보다 약 10 배 빠르고 순진한 의 'n - 1 번 추가' 솔루션보다 약 2 배 빠릅니다.

+0

구현시 '복사 최소화'되지 않습니다. for 루프 내부에서'+ ='가'str.size()'반복을 수행하는 어떤 종류의 루프를 가지고 있음을주의하라. 'str.size()'는 각 외부 루프 반복에서 증가하므로, 각 외부 반복 후에 내부 루프는 더 많은 반복을 수행해야합니다. 귀하와 순진한 '복사 n 시간'구현은 모두 'n * 마침표'문자를 복사합니다. 구현은 초기 '예약'때문에 메모리 할당을 하나만 수행합니다. 나는 당신이 약간의'str'과 큰'n'으로 당신의 구현을 프로파일 한 것 같지만, 큰 str과 작은 n으로 당신의 구현을 프로파일 한 것 같아요. –

+0

@FlorianKaufmann 왜 내 대답을 공격했는지 확실하지 않습니다. 그러나 "복사 최소화"란 말은 '복사 작업'을 의미합니다. 몇 가지 큰 블록을 복사하는 것이 여러 개의 작은 블록을 복사하는 것보다 여러 가지 이유로 더 효율적이라는 생각입니다. 순진한 방법에 비해 입력 문자열에 대한 추가 할당을 피할 수 있습니다. – Daniel

+1

귀하의 솔루션이 순진한 솔루션보다 효율성면에서 훨씬 우수하다고하는 귀하의 주장을 믿지 않는다는 의견이있었습니다. 내 측정에서 순진한 솔루션과 비교할 때 코드는 작은 문자열과 많은 반복에서는 더 빠르지 만 긴 문자열과 반복에서는 느립니다. 몇 개의 큰 블록을 복사하는 것이 많은 작은 블록을 복사하는 것보다 더 높은 성능을 갖는 이유에 대해 자세히 설명하는 링크를 제공 할 수 있습니까? 분기 예측을 생각해 볼 수 있습니다. CPU 캐시에 대해서는 어느 변형이 선호되는지 확실하지 않습니다. –

관련 문제