我正在尝试建立一个程序来解决我最近购买的教科书中的一个问题,这只会让我发疯。
我必须构建一个句子反转器,所以我得到以下内容:
输入=“做或不做,没有尝试。” 输出=“尝试。没有没有,做或做”
这是我到目前为止所得到的:
void ReverseString::reversalOperation(char str[]) {
char* buffer;
int stringReadPos, wordReadPos, writePos = 0;
// Position of the last character is length -1
stringReadPos = strlen(str) - 1;
buffer = new char[stringReadPos+1];
while (stringReadPos >= 0) {
if (str[stringReadPos] == ' ') {
wordReadPos = stringReadPos + 1;
buffer[writePos++] = str[stringReadPos--];
while (str[wordReadPos] != ' ') {
buffer[writePos] = str[wordReadPos];
writePos++;
wordReadPos++;
}
} else {
stringReadPos--;
}
}
cout << str << endl;
cout << buffer << endl;
}
我确信我是在正确的轨道上,但我得到的所有输出都是第一个字(“尝试”。)我一直盯着这段代码,所以我无法取得任何进展。最初我正在检查内部,同时寻找'/ 0'字符,但它似乎不喜欢,所以我把它拿出来。
答案 0 :(得分:5)
除非你感到受虐待,否则请抛弃现有代码,并从std::vector
和std::string
开始(最好是std::vector<std::string>
)。使用向量的std::copy
和rbegin
添加rend
,您就已经完成了。
答案 1 :(得分:5)
在C ++中,在标准库的帮助下,这非常简单:
std::vector< std::string > sentence;
std::istringstream input( str );
// copy each word from input to sentence
std::copy(
(std::istream_iterator< std::string >( input )), std::istream_iterator< std::string >()
, std::back_inserter( sentence )
);
// print to cout sentence in reverse order, separated by space
std::copy(
sentence.rbegin(), sentence.rend()
, (std::ostream_iterator< std::string >( std::cout, " " ))
);
答案 2 :(得分:2)
我在您的代码中看到以下错误:
str[wordReadPos] != ' ' && str[wordReadPos] != 0
否则在扫描第一个单词时它永远不会找到终止空间答案 3 :(得分:2)
为了科学,我试图让你的代码按原样运行。是的,它不是真正的C ++做事方式,但仍具有指导意义。
当然,这只是完成工作的百万种方法之一。我将把它留作练习,以删除此代码在输出中留下的尾随空格;)
我用“编辑”评论了我的更改。
char* buffer;
int stringReadPos, wordReadPos, writePos = 0;
// Position of the last character is length -1
stringReadPos = strlen(str) - 1;
buffer = new char[stringReadPos+1];
while (stringReadPos >= 0) {
if ((str[stringReadPos] == ' ')
|| (stringReadPos == 0)) // EDIT: Need to check for hitting the beginning of the string
{
wordReadPos = stringReadPos + (stringReadPos ? 1 : 0); // EDIT: In the case we hit the beginning of the string, don't skip past the space
//buffer[writePos++] = str[stringReadPos--]; // EDIT: This is just to grab the space - don't need it here
while ((str[wordReadPos] != ' ')
&& (str[wordReadPos] != '\0')) // EDIT: Need to check for hitting the end of the string
{
buffer[writePos] = str[wordReadPos];
writePos++;
wordReadPos++;
}
buffer[writePos++] = ' '; // EDIT: Add a space after words
}
stringReadPos--; // EDIT: Decrement the read pos every time
}
buffer[writePos] = '\0'; // EDIT: nul-terminate the string
cout << str << endl;
cout << buffer << endl;
答案 4 :(得分:1)
由于您使用的是char数组,因此可以使用C字符串库。如果你使用strtok:http://www.cplusplus.com/reference/clibrary/cstring/strtok/
会更容易它需要指针使用,但它会让你的生活更轻松。你的分隔符将是“”。
答案 5 :(得分:1)
您的代码出现问题以及cplusplusish做什么方式的内容尚未写好。但是,我想补充说明方法
效率不高。什么可以帮助您解决此问题,以及将来的许多其他问题是调试器(和穷人的调试器printf)。它将使您能够看到程序在步骤中的实际工作方式,数据发生的情况等等。换句话说,您将能够看到它的哪些部分按预期工作,哪些部分的行为方式不同。如果您使用的是* nix,请不要犹豫,尝试使用gdb。
答案 6 :(得分:0)
这是一个更多的C ++版本。虽然我认为在这种情况下简单性比风格更重要。基本算法很简单,反转单词然后反转整个字符串。
您可以编写与C ++版本一样明显的C代码。我认为在这里编写非夸张的C ++代码并不一定是错的。
void word_reverse(std::string &val) {
size_t b = 0;
for (size_t i = 0; i < val.size(); i++) {
if (val[i] == ' ') {
std::reverse(&val[b], &val[b]+(i - b));
b = ++i;
}
}
std::reverse(&val[b], &val[b]+(val.size() - b));
std::reverse(&val[0], &val[0]+val.size());
}
TEST(basic) {
std::string o = "Do or do not, there is no try.";
std::string e = "try. no is there not, do or Do";
std::string a = o;
word_reverse(a);
CHECK_EQUAL( e , a );
}
具有多个,前导或尾随空格可能是退化情况,具体取决于您实际希望它们的行为方式。