C++ 什么是C++;约定何时需要添加无用的返回语句?

C++ 什么是C++;约定何时需要添加无用的返回语句?,c++,C++,我试图编写一个函数,返回字符串中第一个不重复的字符。我做的算法是: 断言字符串不是空的 遍历字符串并将所有不重复的字符添加到集合中 断言集合不能为空 再次遍历字符串并返回集合中的第一个字符 添加一个无用的return语句以使编译器满意。(任意返回“F”) 显然,我的算法非常“暴力”,可以改进。不管怎么说,它在运行。我想知道是否有更好的方法来实现这一点,同时也想知道对于无用的返回语句的约定是什么。不要害怕严厉地批评我。我正试图成为一个C++的硬汉。p> #包括 #包括 #包括 char fir

我试图编写一个函数,返回字符串中第一个不重复的字符。我做的算法是:

  • 断言字符串不是空的
  • 遍历字符串并将所有不重复的字符添加到集合中
  • 断言集合不能为空
  • 再次遍历字符串并返回集合中的第一个字符
  • 添加一个无用的return语句以使编译器满意。(任意返回“F”)
显然,我的算法非常“暴力”,可以改进。不管怎么说,它在运行。我想知道是否有更好的方法来实现这一点,同时也想知道对于无用的返回语句的约定是什么。不要害怕严厉地批评我。我正试图成为一个C++的硬汉。p>
#包括
#包括
#包括
char first_nonrepeating_char(const std::string&);
int main(){
std::string S=“yodawgIheardyoulike”;
std::cout 0);
std::设置非PChars;
std::string::const_迭代器it=str.begin();
while(it!=str.end()){
如果(nonRepChars.count(*it)==0){
不可撤销。插入(*it);
}否则{
非还原性清除(*它);
}
++它;
}
断言(nonRepChars.size()!=0);
it=str.begin();
while(it!=str.end()){
如果(非累加计数(*it)==1)返回(*it);
++它;
}
return('F');//永远不会发生
}
有一种更简单、更“干净”的方法,但在计算速度上并不比“暴力”快

使用统计输入字符串中每个字符出现次数的表

然后再次检查输入字符串,并返回计数为1的第一个字符

char GetFirstNonRepeatedChar(const char* s)
{
    int table[256] = {0};
    for (int i=0; s[i]!=0; i++)
        table[s[i]]++;
    for (int i=0; s[i]!=0; i++)
        if (table[s[i]] == 1)
            return s[i];
    return 0;
}
注:以上内容适用于ASCII字符串

如果使用不同的格式,则需要更改
256
(当然还有
char

有一种更简单、更“干净”的方法,但计算速度并不比“暴力”快

使用统计输入字符串中每个字符出现次数的表

然后再次检查输入字符串,并返回计数为1的第一个字符

char GetFirstNonRepeatedChar(const char* s)
{
    int table[256] = {0};
    for (int i=0; s[i]!=0; i++)
        table[s[i]]++;
    for (int i=0; s[i]!=0; i++)
        if (table[s[i]] == 1)
            return s[i];
    return 0;
}
注:以上内容适用于ASCII字符串


如果您使用的是不同的格式,则需要更改
256
(当然还有
char

主要的问题是删除警告

理想情况下,你应该能够说

assert( false );  // Should never get here
<>但不幸的是,它并没有消除我使用最多的编译器的所有警告,即VisualC++和G++。 相反,我这样做:

xassert_should_never_get_here();
其中
xassert\u应该\u永远\u在这里获得\u
是一个

    >p>被编译器特定的方法声明为“NordeURN”,例如VisualC++、

    <代码>
  • 有一个
    断言(false)
    来处理调试生成

  • 然后抛出一个
    std::logic_错误

最后两点由宏
XASSERT
完成(在我的代码中它的实际名称是
CPPX_XASSERT
,最好在宏名称中使用前缀,以减少名称冲突的可能性)


当然,不应该结束的断言相当于一个断言,即参数字符串至少包含一个不重复的字符,因此这是函数(其契约的一部分)的一个前提条件,我认为应该通过注释来记录。:-)

在没有前提条件的情况下,有三种主要的“现代C++”编码方式,即

  • 选择一个
    char
    值来表示“无此类”,例如
    “\0”
    ,或

  • 在没有此类异常的情况下引发异常,或者

  • 返回逻辑上可以为“空”的装箱结果,例如



关于算法:当您没有测试第一个不重复的
字符的位置时,您可以通过保持每个字符的计数来避免重新扫描字符串,例如,通过使用
映射而不是

来避免重新扫描字符串。主要的问题只是消除警告

理想情况下,你应该能够说

assert( false );  // Should never get here
<>但不幸的是,它并没有消除我使用最多的编译器的所有警告,即VisualC++和G++。 相反,我这样做:

xassert_should_never_get_here();
其中
xassert\u应该\u永远\u在这里获得\u
是一个

    >p>被编译器特定的方法声明为“NordeURN”,例如VisualC++、

    <代码>
  • 有一个
    断言(false)
    来处理调试生成

  • 然后抛出一个
    std::logic_错误

最后两点由宏
XASSERT
完成(在我的代码中它的实际名称是
CPPX_XASSERT
,最好在宏名称中使用前缀,以减少名称冲突的可能性)


当然,不应该结束的断言相当于一个断言,即参数字符串至少包含一个不重复的字符,因此这是函数(其契约的一部分)的一个前提条件,我认为应该通过注释来记录。:-)

在没有前提条件的情况下,有三种主要的“现代C++”编码方式,即

  • 选择一个
    char
    值来表示“无此类”,例如
    “\0”
    ,或

  • 在没有此类异常的情况下引发异常,或者

  • 返回逻辑上可以为“空”的装箱结果,例如


关于算法:如果未测试第一个非重复
char
的位置,可以通过保持每个字符的计数来避免重新扫描字符串,例如使用
map
而不是