2014-12-19 81 views
1

我的下一个任务有问题。问题是:字典顺序,字符串,C++

让我们假设我们有一个字母A(c,a,b)。写功能:

int my_strcmp(char S1[], char S2[]); 

它将比较字符数组S1和S2,写在A alpak。 结果应该是:

0,如果S1 == S2
-1,如果S1是字典顺序比S2
+1较小,如果S1是字典顺序比S2

性能测试 - 大案例:

aa”“cc”=> 1
ac”, “a”=> 1
c” “ac”=> -1
bc” “ab”=> 1
bc” “ac”=> 1

#include <stdio.h> 
#include <stdlib.h> 
#include <cstdlib> 
#include <iostream> 
#include <string> 
#include <algorithm> 

#define T_SIZE 1001 

int my_strcmp(char S1[], char S2[]); 
int compCh(char a, char b); 

int main(){ 
    int t; 
    char S1[T_SIZE], S2[T_SIZE]; 
    scanf_s("%d", &t); 

    while(t) { 

    std::cin.getline(S1,T_SIZE,' '); 
    std::cin.getline(S2, T_SIZE); 
    printf("%d\n", my_strcmp(S1, S2)); 

    t--; 
    } 
    system("pause"); 
    return 0; 
} 

int compCh(char a, char b) { 
    int x, y; 
    switch (a) { 
    case 'c': 
     x = 0; 
     break; 
    case 'a': 
     x = 1; 
     break; 
    default: 
     x = 2; 
     break; 
    } 
    switch (b) { 
    case 'c': 
     y = 0; 
     break; 
    case 'a': 
     y = 1; 
     break; 
    default: 
     y = 2; 
     break; 
    } 
    return (x - y); 
} 

int my_strcmp(char S1[], char S2[]) { 

    for (int i = 0; (i<std::min(strlen(S1), strlen(S2))); i++) { 
     if (i == 0) { 
      if (compCh(S1[i+1], S2[i]) == 0) { 
       continue; 
      } 
      else if (compCh(S1[i+1], S2[i]) < 0) { 
       return -1; 
      } 
      else { 
       return 1; 
      } 
     } 
     else { 
      if (compCh(S1[i], S2[i]) == 0) { 
       continue; 
      } 
      else if (compCh(S1[i], S2[i]) < 0) { 
       return -1; 
      } 
      else { 
       return 1; 
      } 
     } 
    } 
    if (strlen(S1) > strlen(S2)) { 
     return 1; 
    } 
    else { 
     return -1; 
    } 
} 

我不知道为什么它现在正在工作。我想的是,在当

my_strcmp

函数I == 0,则S1 [I]将等于一些奇怪看不见符号。即使tho,用if语句改变函数后,如果我== 0,捕捉程序仍然无法正常工作。我不知道哪里出错,因为这个程序正在通过在线评审程序进行检查。

我并不是要求现成的答案,但请指出我犯的错误。

+0

你确定当一个字符串的前缀长时,字符串应该比较小吗? – Deduplicator 2014-12-19 12:01:32

+3

在调试器中运行你的程序,并逐行浏览代码,看看它在做什么。 – 2014-12-19 12:02:56

+0

更正了这个i == 0。由于某些原因,即使S1 =“a”,那么我可能得到S1 [1],这将等于“a”。它只在for循环的第一次运行中可行。接下来的似乎很好。 – Setzo 2014-12-19 12:06:29

回答

0

考虑到不需要使用函数compCh来确定两个字符是否相等。因此binstead的

if (compCh(S1[i], S2[i]) == 0) { 

你可以写简单的

if (S1[i] == S2[i]) { 

你也需要检查两个字符串是否相等的循环之后。此外,目前还不清楚是什么你正在尝试做的,当我等于0

请尝试以下

#include <iostream> 
#include <iomanip> 
#include <utility> 

int weight(char c) 
{ 
    const char order[] = "cab"; 
    const int N = 3; 
    int n = 0; 

    while (n < N && order[n] != c) ++n; 

    return n == N ? 0 : ++n; 
} 

int my_strcmp(const char s1[], const char s2[]) 
{ 
    while (*s1 && *s1 == *s2) ++s1, ++s2; 

    return *s1 == *s2 ? 0 : (weight(*s1) < weight(*s2) ? - 1 : 1); 
} 

int main() 
{ 
    for (auto p : { std::make_pair("aa", "cc"), 
        std::make_pair("ac", "a"), 
        std::make_pair("c", "ac"), 
        std::make_pair("bc", "ab"), 
        std::make_pair("bc", "ac"), 
        }) 
    { 
     std::cout << "\"" << std::setw(2) << p.first 
        << "\" \"" << std::setw(2) << p.second 
        << "\" => " << my_strcmp(p.first, p.second) 
        << std::endl; 
    }     

    return 0; 
} 

程序输出是

"aa" "cc" => 1 
"ac" " a" => 1 
" c" "ac" => -1 
"bc" "ab" => 1 
"bc" "ac" => 1 

正如你所看到的功能非常简单明了。

0

通过封装重复代码重构代码:

static inline char map_alpha(char x) { 
    switch(x) { 
    case 'a': return 'b'; 
    case 'b': return 'c'; 
    case 'c': return 'a'; 
    case 0: return '\xFF'; // A shorter string is bigger [!] 
    case '\xFF': return 0; // " 
    } 
    return x; 
} 

现在在典型的字符串比较功能使用它:

// Added const, because the function never changes its inputs 
int compare_mapped(const char* a, const char* b) { 
    while(*a && *a == *b) // No need to map here, its bijective 
     ++a, ++b; 
    int r = 0 + (unsigned char)map_alpha(*a) - (unsigned char)map_alpha(*b); 
    // cast to unsigned char, because char might be signed 
    return r < 0 ? -1 : !!r; // normalize return, though that's curious. 
} 
-1

这应该是一个相当简单的算法,一旦你写下比较。

你的错误就是,你做要删除compCh(S1[i+ 1], S2[i]) == 0) {

+ 1需求则应当一切正常。

也就是说,您的my_strcmp似乎有点不必要的复杂。我已经写的my_strcmp的简化版本,低于该仍然使用compCh

int my_strcmp(char S1[], char S2[]){
const int S1size = strlen(S1);
const int S2size = strlen(S2);
const auto size = std::min(S1size, S2size);
const auto S1end = std::next(S1, size);
const auto result = std::mismatch(S1, S1end, S2);

return result.first == S1end ? std::min(1, std::max(-1, S1size - S2size)) : compCh(*result.first, *result.second);
}

如果您使用Visual Studio进行编译,您将得到一个错误,除非在最后一个参数std::mismatch上使用stdext::checked_array_iterator。使用该行,而不是将解决这个问题:const auto result = std::mismatch(S1, S1end, stdext::checked_array_iterator<char*>(S2, size));

其他一些事情需要注意的:

  1. 您应该确认您的比较或之前的地方,琴弦符合你的三个字母组成的字母表。
  2. 您需要处理空白。
  3. 您需要处理大写字母或lcase运行之前的所有内容my_strcmp