词典顺序,字符串,c ++
Lexicographic order, strings, c++
我的下一个任务有问题。问题是:
让我们假设我们有一个字母A(c,a,b(。写入功能:
int my_strcmp(char S1[], char S2[]);
这将比较用 A alhpabet 编写的字符数组 S1 和 S2。 结果应为:
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("%dn", 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] 将等于一些奇怪的看不见的符号。即使这样,在使用 if 语句更改函数后,如果 i==0 捕获,程序仍然无法正常工作。我不知道错误在哪里犯的,因为该程序正在由在线法官程序检查。
我不是在要求现成的答案,但请指出我所犯的错误。
使用函数compCh
来确定两个字符是否相等。因此,代替
if (compCh(S1[i], S2[i]) == 0) {
你可以简单地写
if ( S1[i] == S2[i] ) {
同样在循环之后,您必须检查两个字符串是否相等。也不清楚当 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
如您所见,这些功能非常简单明了。
通过封装重复代码来重构代码:
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.
}
一旦你写完了比较,这应该是一个相当简单的算法。
你的错误只是你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));
其他一些需要注意的事项:
- 您应该在比较中或之前的某个地方验证字符串是否符合您的三个字母字母表。
- 您需要处理空格。
- 您需要处理大写字母,或者在运行
my_strcmp
之前lcase
所有内容。
- 按字母顺序对字符串中的字母进行排序,而无需使用内置的 sort()
- 按字母顺序对C++问题中的子字符串索引进行分区
- 提高从排序字符串中获取字母顺序的顺序复杂性
- 字符串变量顺序
- 高效的字符串截断算法,按顺序删除相等的前缀和后缀
- 反转字符串中单词的位置,而不更改 O(1) 空格限制中特殊字符的顺序
- C++按字母顺序排列的字符串数组
- 如何在 c++ 中按字母顺序排列数组中的字符串?
- C++ 按数值对元组<字符串、浮点数>然后按字典顺序排序的向量
- 如何根据长度然后字母顺序对数组字符串进行排序?
- C 在向量的向量中按字母顺序排序字符串
- 将字符串值分配给Char数组以相反的顺序进行循环
- 检索字符串的第一个字符,并在C++中按字母顺序进行比较
- 将字符指针按顺序存储在 map 中 std::map<char*, int> mymap。将其存储为字符或字符串不是一个选项
- 添加字符串和文字,顺序如何影响是否可以正确添加字符串
- 我不知道如何创建一个以数字/字母顺序打印出我的整数或字符串的程序
- 按字母顺序对字符串数组进行排序C++
- 在 C++ 中使用链表按字母顺序对字符串进行排序
- 如何将整数向量转换为 2 位十六进制并按顺序添加到 c 字符串?
- c++:对于与字符串顺序无关的字符串序列的哈希函数的建议