反转字符串中单词的字母

时间:2013-06-17 12:29:10

标签: c++ arrays pass-by-reference

我想要反转字符串中单词的字母,并且必须将它存储在同一个数组中。例如:i / p:你好,你怎么样?我很喜欢。我写了这个程序,但它只打印相同的字符串而没有反转,程序没有终止它继续打印的东西。我找不到错误。请帮帮我,告诉我正确的代码。

#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所需的输出:你好,你怎么样:ihh hi hhi HHI。仍然需要你的帮助。

8 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

这个for循环以分号终止:

for(k=i1-j1;k<i1;k++);
                    ^^^

答案 2 :(得分: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;

  }

答案 3 :(得分: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())
         ));
    }

}

答案 4 :(得分:0)

您通过j而没有分配值。所以这将是垃圾。

答案 5 :(得分:0)

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

1)

int j;

应替换为

int j=0;

并且

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

for循环后的分号需要删除。

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

答案 6 :(得分:0)

this site.上显示了一个类似的例子。他们也使用了几乎相同的方法(通过计算空格数来反转每个单词),借助堆栈数据结构。 />
确保在您的环境中安装了STL库以运行此代码。
最好在linux平台上运行此代码。

答案 7 :(得分: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;

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