【问题标题】:Why my C code gives incorrect output for next palindrome为什么我的 C 代码为下一个回文给出了不正确的输出
【发布时间】:2017-09-12 08:43:27
【问题描述】:

我有一个 C 代码(查找 next smallest palindrome),当我在本地 Mac(osx:10.11.4)和 ideone 中运行时,它会为相同的输入给出错误的结果。它不会对所有输入错误,但对某些输入错误。

例如这里是由 ideone 运行的:http://ideone.com/T4tqak

这是我对相同输入的结果:

在本地输入:

8
97795375756122352572879826552151654387112262
1892388497169516734992356528466
19891859448286167812
47737795782241879811566697829238862994263278849942632926438725
857751275744476297149515661
699
5119783738665448121162642286
4177118624313412937235746451

本地输出:

97795375756122352572877827525322165757359779
1892388497169516159617948832981
19891859444495819891
47737795782241879811566697829233292879666511897814228759773774
857751275744474447572157758
707
5119783738665445668373879115
4177118624313443134268117714

这里是C代码供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int all_nine(char* input){
  int result = 1, i;
  for(i = 0; i < strlen(input); ++i){
    if(input[i] != '9')
      return 0;
  }
  return result;
}

char* increase_one(char* input){
  int i;
  for(i = strlen(input) - 1; i >= 0; --i) {
    if(input[i] < '9'){
      input[i] += 1;
      break;
    }
    else{
      input[i] = '0';
    }
  }
  return input;
}


char* increase_make_palin(char* input){
  int input_len = strlen(input);
  int half_len = input_len%2 ? input_len/2 : input_len/2 - 1;
  int carry = 1, i;
  for(i = half_len; i >= 0; --i) {
    int cur_val = input[i] - '0';
    carry = (cur_val + carry) / 10;
    int new_val = (cur_val + carry) % 10;
    input[i] = input[input_len - 1 - i] = '0' + new_val;
  }
  return input;
}
char* next_palin_for_me(char* input){
    int input_len = strlen(input);
    int half_len = input_len/2  - 1, i;
    for(i = half_len; i >= 0; --i) {
      if(input[i] > input[input_len - 1 - i]){
        input[input_len - 1 - i] = input[i];
      } else {
        return increase_make_palin(input);
      }
    }
    return input;
}

char* next_palin(char* input){
  int input_len = strlen(input);
  if(all_nine(input)){
    return next_palin_for_me(increase_one(input));
  }
  if(input_len == 1){
    input[0] += 1;
    return input;
  }
  input = increase_one(input);
  return next_palin_for_me(input);
}

int main() {
  int n, i;
  scanf("%d", &n);
  char input[1000010];
  for(i = 0 ; i < n ; i++){
    scanf("%s", input);
    char* result = next_palin(input);
    printf("%s\n", result);
  }
  return 0;
}

【问题讨论】:

  • 请将有问题的代码添加到问题本身中。你有 13krep,现在你肯定知道MCVE 代表什么!
  • @AnttiHaapala 我已经添加了它,但是我的问题更多是关于如何使编译器相同,但最好在这里拥有它。
  • 您的意见是什么?可能是因为输入字符串的编码不同吗? Unicode vs ASCII?
  • 我无法在本地重现您的结果。如果第一个输入很重要,那么请只提供第一个。这还不是 MCVE - 不需要输入计数等,只需输入 97795375756122352572879826552151654387112262 就足够了,这 应该 导致 97795375756122352572888827525322165757359779(但它没有,甚至在我的电脑上)
  • 您的“本地”结果似乎不正确。您是否尝试过在调试器中逐步执行?

标签: c macos compilation execution


【解决方案1】:

问题出在这里:

char* increase_make_palin(char* input){
    ...
    carry = (cur_val + carry) / 10;
    int new_val = (cur_val + carry) % 10;
    ...
}

请注意,您在使用之前更改carry将这两行的顺序颠倒,您的代码将按预期工作。

您可以使用 8799 作为测试输入,看看它是如何工作的。您可以自己发现这一点,方法是使用调试器逐步完成,或者将您的失败案例简化为更简单的案例。

至于为什么它在ideone上用错误的代码给出了正确的答案(如果确实如此;我没有尝试过),我只能猜测可能是数字的编码不同,这会造成麻烦用你的“-'0'”方法。

编辑:

char* increase_make_palin(char* input){
  int input_len = strlen(input);
  int half_len = input_len%2 ? input_len/2 : input_len/2 - 1;
  int carry = 1, i = half_len;
  while(i > 0){
    if(input_len%2 == 0){
      if(input[i] == input[input_len - 1 - i]) {
        i--;
        continue;
      }
      if(input[i] > input[input_len - 1 - i]) {
        carry = 0;
        break;
      }
      else{
        break;
      }
    }
    if(input_len%2){
      if(input[i-1] == input[input_len - i]){
        i--;
        continue;
      }
      if(input[i-1] > input[input_len - i]){
        carry = 0;
        break;
      }
      else{
        break;
      }
    }
  }
  for(i = half_len; i >= 0; --i) {
    int cur_val = input[i] - '0';
    int new_val = (cur_val + carry) % 10;
    carry = (cur_val + carry) / 10;
    input[i] = input[input_len - 1 - i] = '0' + new_val;
  }
  return input;
}

【讨论】:

  • 你是对的,还有一个小问题,我刚刚发现,我在你的回答中也添加了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 2016-05-05
  • 1970-01-01
  • 2014-10-08
  • 2022-11-13
  • 2023-02-12
相关资源
最近更新 更多