在 C++ 中插入已排序的结构数组
我必须使用 C++ 中的数组来实现一个向量,该数组用于计算输入中唯一单词的数量。它读取输入,然后将单词添加到包含其计数和唯一单词的结构中,然后将其添加到向量中。我已经成功实现了插入。问题是我无法使插入/递增唯一字数正常工作(元素未添加到向量中)。这是我的代码:
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include "MyVector.h"
using namespace std;
struct wordCount{
string val;
int count;
};
int main(int argc, char** argv) {
enum { total, unique,individual } mode = total;
for (int c; (c = getopt(argc, argv, "tui")) != EOF;) {
switch(c) {
case 't': mode = total; break;
case 'u': mode = unique; break;
case 'i': mode = individual; break;
}
}
argc += optind;
argv += optind;
string word;
Vector<wordCount> words;
Vector<wordCount>::iterator it;
int count = 0;
while (cin >> word) {
count++;
if(mode == unique || mode == individual){
for(it=words.begin();it != words.end();it++){
if((it-1)->val <= word && it->val >= word){
// Found word, increment its count
if(it->val == word){
it->count++;
break;
}
// Otherwise insert the new unique word
else{
cout << "adding unique word" << endl;
wordCount* wc;
wc = new wordCount;
wc->val = word;
wc->count = 1;
words.insert(it,*wc);
break;
}
}
}
}
}
switch (mode) {
case total: cout << "Total: " << count << endl; break;
case unique: cout << "Unique: " << words.size() << endl; break;
case individual:
for(it=words.begin();it!=words.end();it++){
cout << it->val << ": " << it->count << endl;}
break;
}
}
I have to implement a vector using an array in C++ that is used to count the number of unique words from the input. It reads the input and then adds to the words to a struct which contains its count and the unique word and then this is added to the vector. I have successfully implemented insert. The problem is that I can't get the inserting/ incrementing unique word count to work (elements aren't added to the vector). Here is my code:
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include "MyVector.h"
using namespace std;
struct wordCount{
string val;
int count;
};
int main(int argc, char** argv) {
enum { total, unique,individual } mode = total;
for (int c; (c = getopt(argc, argv, "tui")) != EOF;) {
switch(c) {
case 't': mode = total; break;
case 'u': mode = unique; break;
case 'i': mode = individual; break;
}
}
argc += optind;
argv += optind;
string word;
Vector<wordCount> words;
Vector<wordCount>::iterator it;
int count = 0;
while (cin >> word) {
count++;
if(mode == unique || mode == individual){
for(it=words.begin();it != words.end();it++){
if((it-1)->val <= word && it->val >= word){
// Found word, increment its count
if(it->val == word){
it->count++;
break;
}
// Otherwise insert the new unique word
else{
cout << "adding unique word" << endl;
wordCount* wc;
wc = new wordCount;
wc->val = word;
wc->count = 1;
words.insert(it,*wc);
break;
}
}
}
}
}
switch (mode) {
case total: cout << "Total: " << count << endl; break;
case unique: cout << "Unique: " << words.size() << endl; break;
case individual:
for(it=words.begin();it!=words.end();it++){
cout << it->val << ": " << it->count << endl;}
break;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果没有看到你的实现,很难说什么
向量
。如果我们假设它符合标准容器约定(并且尝试这样做时没有错误):你
从 it.begin() 开始迭代,但立即访问
it-1
。对于标准容器来说,这是未定义的行为。 (我
不知道它会对您的 Vector` 实现做什么,
但需要一些棘手的代码才能使其工作。)
在更高的层次上,似乎存在一个基本的不一致:你是
保持向量排序,但仍然使用线性搜索。如果
你正在使用线性搜索,没有必要保留
向量排序;只需使用:(
虽然我可能会追加到末尾,但将迭代器恢复为
新插入的元素,并将其视为已找到)。
或者,如果您要保持向量排序,请使用二进制
搜索,而不是线性搜索。
无论哪种情况,都将搜索放在单独的函数中。 (如果这
不是家庭作业,我想说只需使用
std::vector
即可std::find_if
或std::lower_bound
。)另外,为什么
new
位于最里面的else
中?更合理的方法是为
wordCount
提供一个构造函数(将计数设置为 0),然后执行以下操作:
found
的定义将取决于您是否使用是否采用二分查找。就标准而言,这将是
要么:
或者
你应该努力做类似的事情,
一个单独的查找函数,返回
end
或未找到值时插入的位置。
这使各种关注点清晰分开,并避免
代码中的过度嵌套。 (你可能应该尝试
一般来说,要避免
break
,而在多重嵌套的if
中,它是完全不可接受——你会注意到其中之一
其他回答的人错过了他们,并误解了他们
因此控制流。)
It's hard to say anything without seeing your implementation of
Vector
. If we assume it adheres to the standard containerconventions (and doesn't have an error in trying to do so): you
iterate starting with
it.begin(), but immediately access
it-1. That's undefined behavior for a standard container. (I
Vector`,don't know what it will do with your implementation of
but it would take some tricky code to make it work.)
At a higher level, there seems a basic inconsistency: you're
keeping the vector sorted, but still using linear search. If
you're using linear search, there's no point in keeping the
vector sorted; just use:
(although I'd probably append to end, recover the iterator to
the newly inserted element, and treat it as if it were found).
Alternatively, if you're keeping the vector sorted, use a binary
search, not a linear search.
In either case, put the search in a separate function. (If this
wasn't homework, I'd say just use
std::vector
and eitherstd::find_if
orstd::lower_bound
.)Also, why the
new
in the innermostelse
? A more reasonableapproach would be to provide a constructor for
wordCount
(which sets the count to 0), and do something like:
The definition of
found
will depend on whether you're usingbinary search or not. In terms of the standard, this would be
either:
or
You should probably strive for something similar, with
a separate lookup function, returning either
end
, or theposition for the insertion when the value isn't found.
This keeps the various concerns clearly separated, and avoids
the excessive nesting in your code. (You should probably try to
avoid
break
in general, and in multiply nestedif
s, it iscompletely inacceptable—you'll notice that one of the
other people answering missed them, and misunderstood the
control flow because of it.)
那么,为什么不使用
地图
呢?这正是它的用途,从一件事映射到另一件事。在您的情况下,从string
(单词)到int
(出现次数)。还是必须使用向量?Well, why don't you use a
map
? That's exactly what it's for, mapping from one thing to another. From astring
(the word) to anint
(the number of occurences) in your case. Or do you have to use a vector?尝试使用 std::map。
Counter 函子可能看起来像这样
使用 std::vector
Try to use a std::map.
The Counter functor could look like this
Using a std::vector