0

我想反转字符串中单词的字母,并且必须将其存储在同一个数组中。示例: i/p: hi how are you o/p: ih woh era uoy。我写了这个程序,但它只是打印相同的字符串而不反转,并且程序没有终止它继续打印一些东西。我找不到错误。请帮助我并告诉我正确的代码。

#include<iostream.h>
#include<conio.h>
#include<stdio.h>

void stre(char (&a1)[20], int j1, int i1)
{
    char b[20];
    for(int k=i1-j1;k<i1;k++)
        b[k]=a1[i1-k-1];
    for(k=i1-j1;k<i1;k++);
        a1[k]=b[k];
}


void main()
{
    clrscr();
    int j;
    char a[20];
    gets(a);
    for(int i=0;a[i]!='\0';i++)
    {
        j++;
        if(a[i]==' ')
        { 
            stre(a,j,i);
            j=0;
        }
    }
    stre(a,j,i);
    for(j=0;j<i;j++)
    cout<<a[j];
    getch();
}

朋友们,在你回答之后,我删除了 for 循环中的分号,并且还初始化了 j=0,但我现在仍然无法为 i/p:hi 获得所需的输出,你好吗 o/p:ihh hi hhi hhi。仍然需要你的帮助。

4

8 回答 8

5
for(k=i1-j1;k<i1;k++);
  a1[k]=b[k];

for 循环后的分号可防止最后一个操作多次发生。

于 2013-06-17T12:31:41.910 回答
1

此 for 循环由分号终止:

for(k=i1-j1;k<i1;k++);
                    ^^^
于 2013-06-17T12:31:55.680 回答
1

尝试

  #include <iostream>
    using namespace std;


       int main() {

int j =0;
char a[20] = "hi how are you";
char b[20] = "";
    int l=0;
    for(int i=0;a[i]!='\0';i++){

        if(a[i]==' ' ||a[i+1]=='\0'){
          cout<<j<<' '<<i;
           if(a[i+1]=='\0'){
               b[l++] = ' ';


           }


          for(int k=i;k>=j;k--){
              b[l]=a[k];
              l++;
          }
          for(int k=j;k<=i;k++){
            cout<<b[k];
            a[k] = b[k];
          }  


        cout<<endl;
        j = i+1;

        }
    }
   cout << a;
    return 0;

  }
于 2013-06-17T12:32:20.097 回答
1

这是一个无论如何都不完美的版本,但至少,它试图更像 C++ 而不是 C:

http://ideone.com/f5vciW

第一:分词成单词和空格序列

//the spaces should be preserved
std::string test("hi   how are you"),reference("ih   woh era uoy");
 std::vector<std::string> tokens;
tokenize(test,tokens);

然后反转令牌

for (auto& token : tokens)
    std::reverse(token.begin(),token.end());

将标记组装到字符串缓冲区中

std::stringstream buf;
for (auto token : tokens)
    buf<<token;

检查结果

std::string res=buf.str();
assert(res==reference);

标记器看起来像这样:

template <typename TContainer,typename TString>
void tokenize(TString input,TContainer& res)
{

    if (input.length()<2) {
        res.push_back(input);
        return;
    }

    typename TString::const_iterator pos=input.begin();
    bool space_state=std::isspace(input[0],std::locale());
    for (typename TString::const_iterator it=input.begin(); it!=input.end();
            ++it) {
        bool is_space=std::isspace(*it,std::locale());
        if (is_space!=space_state) {
            res.push_back(TString(pos,it));
            pos=it;
            space_state=is_space;
        }
    }

    //the rest
    if (pos!=input.end()) {
        res.push_back(
         TString(
          pos,
          static_cast<typename TString::const_iterator>(input.end())
         ));
    }

}
于 2013-06-17T12:35:01.580 回答
0

您在 j未分配值的情况下通过了。所以这将是垃圾。

于 2013-06-17T12:32:22.297 回答
0

我可以在您的代码中看到两件事可能不会产生预期的输出:

1)

int j;

应该替换为

int j=0;

for(k=i1-j1;k<i1;k++);
    a1[k]=b[k];

for 循环后面的分号需要去掉。

仅供参考,不建议混合使用 C 和 C++ 代码(这会损害可读性)。请坚持其中任何一个。

于 2013-06-17T12:51:02.323 回答
0

该站点上显示了一个类似的示例。在堆栈数据结构的帮助下,他们还使用了与您选择的几乎相同的方法(通过计算空格数来反转每个单词)。

确保在您的环境中安装了 STL 库以运行此代码。
最好在 linux 平台上运行此代码。

于 2013-06-17T16:47:33.927 回答
0

这是另一个更短的版本,在不使用额外缓冲区的情况下进行内联反转:

http://ideone.com/hs9NZ7

标记器的标准是isspace条件的变化:

auto next_token=
 [&](char c) {
       return std::isspace(c,loc)!=std::isspace(*pos,loc);
 };

使用它我们可以遍历输入字符串并访问令牌:

for (auto it=std::find_if(pos,test.end(),next_token);
          it!=test.end();
          it=std::find_if(pos,test.end(),next_token))

反转它们并更新当前位置

std::reverse(pos,it);
pos=it;

并且不要忘记剩余的令牌。

于 2013-06-18T12:14:40.620 回答