我刚参加考试,要求我回答以下问题:
class Strings {
private:
char str[80];
int StrLen;
public:
// Constructor
Strings() {
StrLen=0;
};
// A function for returning the length of the string 'str'
int GetStrLen(void) {
};
// A function to inser a character 'ch' at the end of the string 'str'
void InsertChar(char ch) {
};
// A function to reverse the content of the string 'str'
void StrReverse(void) {
};
};
我给出的答案是这样的(请参见下面的内容)。我的问题之一是,使用了许多额外的变量,这使我相信没有以最好的方式做到这一点,而另一件事是那没有用...。
class Strings {
private:
char str[80];
int StrLen;
int index; // *** Had to add this ***
public:
Strings(){
StrLen=0;
}
int GetStrLen(void){
for (int i=0 ; str[i]!='\0' ; i++)
index++;
return index; // *** Here am getting a weird value, something like 1829584505306 ***
}
void InsertChar(char ch){
str[index] = ch; // *** Not sure if this is correct cuz I was not given int index ***
}
void StrRevrse(void){
GetStrLen();
char revStr[index+1];
for (int i=0 ; str[i]!='\0' ; i++){
for (int r=index ; r>0 ; r--)
revStr[r] = str[i];
}
}
};
如果有人能大致解释我的问题,为什么?是回答该问题的最佳方式,我将不胜感激。同样,我的教授如何关闭“};”这样的每个类函数,我认为那仅用于结束类和构造函数。
非常感谢你的帮助。
最佳答案
首先,琐碎的};
问题只是样式问题。当我将函数体放在类声明中时,我也会这样做。在这种情况下,;
只是一个空语句,不会更改程序的含义。可以将其保留在函数末尾(但不能保留在类末尾)。
这是您编写的一些主要问题:
str
的内容。不能保证以\0
字节开始。 index
,只在GetStrLen
中进行设置。程序启动时,其值可能为-19281281。如果有人在调用InsertChar
之前先调用GetStrLen
怎么办? index
中更新InsertChar
。如果有人连续两次调用InsertChar
怎么办? StrReverse
中,您创建了一个称为revStr
的反向字符串,但是您从不对其进行任何操作。 str
中的字符串保留相同的后缀。 让我感到困惑的是,为什么创建了一个名为
index
的新变量,大概是为了跟踪字符串中倒数第二个字符的索引,而为此已经存在一个名为StrLen
的变量,而您却完全忽略了它。倒数第二个字符的索引是字符串的长度,因此您应该保持字符串的长度为最新,并使用例如int GetStrLen(void){
return StrLen;
}
void InsertChar(char ch){
if (StrLen < 80) {
str[StrLen] = ch;
StrLen = StrLen + 1; // Update the length of the string
} else {
// Do not allow the string to overflow. Normally, you would throw an exception here
// but if you don't know what that is, you instructor was probably just expecting
// you to return without trying to insert the character.
throw std::overflow_error();
}
}
但是,您的字符串反转算法完全是错误的。考虑一下代码中所说的内容(假设
index
在其他地方已正确初始化和更新)。它说:“对于str
中的每个字符,都用此字符向后覆盖整个revStr
”。如果str
以"Hello World"
开始,则revStr
最终将以"ddddddddddd"
结尾,因为d
是str
中的最后一个字符。您应该做的是这样的:
void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
}
注意它是如何工作的。说
StrLen = 10
。然后,我们将str
的位置0复制到revStr
的位置9,然后将str
的位置1复制到9
的revStr
等位置,依此类推,直到将StrLen - 1
的位置str
复制到revStr
的位置0中。但是然后您在
revStr
中得到了一个反向字符串,而您仍然缺少将其放回str
中的那一部分,因此完整的方法看起来像void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
for (int i = 0; i < StrLen; ++i) {
str[i] = revStr[i];
}
}
在不需要临时字符串
revStr
的情况下,有一些更聪明的方法可以执行此操作,但是以上内容功能完善,可以正确解决此问题。顺便说一句,您实际上根本不需要担心此代码中的NULL字节(
\0
)。您正在使用(或至少应该使用StrLen
变量来跟踪字符串的长度)这一事实,因此不需要使用前哨结束符,因为使用StrLen
时您已经知道应忽略str
的内容。关于字符串类实现的C++考试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2791852/