6

我正在尝试做一个小任务,要求将数字转换为电话键盘的字母,例如,如果输入是 222,则表示电话按钮“2”(http://upload.wikimedia.org/wikipedia/commons/7/ 7d/Telephone-keypad.png)被按下 3 次,输出应该是“C”等等。所以我首先应该做的是将所有序列,例如 22255-444 分成 222 、 55 、 - 、 444 和然后我想弄清楚一切,但现在的问题是我的函数无法读取最后一个序列

#include <iostream>
#include <fstream>
using namespace std;
//-------------------------------------------------------------------------

void encode(string text, string &result, int &i)
{
 char keyboard[10][4] = {
    {' ',' ',' ',' '},
    {'.','?','!','.'},
    {'a','b','c','a'},
    {'d','e','f','d'},
    {'g','h','i','g'},
    {'j','k','l','j'},
    {'m','n','o','m'},
    {'p','r','q','s'},
    {'t','u','v','t'},
    {'w','x','y','z'}
  };

  int j;
  for(j = i; j<text.size();j++)
  {
    if(text[i] != text[j] || j == text.size())
    {
        result = text.substr(i, j-i);
        i = j-1;
        break;
    }

  }
  cout << result << endl;

}



int main()
{
  ifstream fd("sms.in");
  string text;
  string result;
  getline(fd, text);
  for(int i = 0; i<text.size();i++)
  {
    encode(text, result, i);
  }
  return 0;
}

作为一个测试,我现在使用这个输入:5552-22-27777,输出应该是 555 2 - 22 - 2 7777,但对我来说它是 555 2 - 22 - 2 2 2 2 2。

4

2 回答 2

2

在本if声明中:

if(text[i] != text[j] || j == text.size())

第二个条件 ( j == text.size()) 永远不会为真,因为循环将在此之前终止。因此,当您到达字符串末尾时,result和的值i将不会正确更新。

您可以做的是从循环中删除终止条件(不必有一个,因为无论如何您都会跳出循环)。并且您将需要反转条件的顺序,if这样您就不会读到字符串的末尾:

for(j = i; ;j++)
{
    if (j == text.size() || text[i] != text[j])
    ...
于 2012-12-12T09:24:52.243 回答
0

我会把最后一点从 for 循环中拉出来,它并不真正属于那里,因为它是一种特殊情况。我还消除了一些其他看起来不必要的东西,并修复了循环的内部。看看这一切对你来说是否有意义。

我删除了键映射声明,因为它没有在您的示例中使用,并且我们重视这里所谓的“最小工作示例”作为一种有效地隔离和讨论问题的方式。

请注意,我已尝试将所有编码工作移到单个函数中并移出 main() 函数。这释放了 main 来处理程序的高级部分。在我标记为“在这里解码”的行中,如果您要这样做,您可以调用另一个函数,将数字字符串转换为字符。

我已经标记了特殊情况并明确地将其移出 for 循环,以便 for 循环中的所有内容都可以进行相同的处理。这比试图让 for 循环做所有事情要好。

我不同意那个逻辑i=j-1,所以我改变了它(我确实测试了这个)。

我还切换到直接从命令行读取输入,以便更快地进行测试。

#include <string>在开头添加了指令,以便程序可以编译。

将所有编码工作放在单个函数中,将函数声明简化为单个参数。

我切换了括号以符合我自己对 One True Style 的理解。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void encode(string text) {
  int j=0,i=0; //Declare j here so we can use in special case
  for(j=0; j<text.size(); j++){
    if(text[j] != text[i]){
      cout << text.substr(i, j-i) << endl; //Decode here
      i = j;
    }
  }
  cout << text.substr(i,j-1) << endl; //Decode here. Special case
}

int main(){
  string text;

  getline(cin, text);
  encode(text, result);

  return 0;
}
于 2012-12-12T09:34:02.483 回答