您好我跟随Bjarne Stroustrup"编程 - 使用C ++的原则和实践"我在第3章做了#34;重复的单词检测程序","试试这个"练习,我在低估下面的代码时遇到了一些困难:
int main()
{
string previous = " "; // previous initialised as white space
string current; // assign string varibable as current
while(cin>>current) // read a stream of words
{
if (previous == current) // check if word is the same as last
{
cout << "repeated word: " << current << "\n";
}
previous = current;
}
}
我不明白为什么一旦重复两个单词,程序就不会打印到屏幕上,只有当你按下回车键时它才会重复打印。如果有人能够解释这一点,我将非常感谢!
答案 0 :(得分:0)
那就是cin如何运作。
Cin读取第一个单词但仅在检测到“\ n”时返回。当你按“输入”时会发生这种情况。这意味着您可以根据需要进行编写,但如果您没有点击“输入”,则cin不会停止阅读。
cin背后还有更多,以及所有这些机制如何运作,但我认为这足以让你开始。尝试阅读更多章节!
编辑:为了清晰起见改变了单词。请看下面评论中的@Jaka Konda示例。
答案 1 :(得分:0)
在public class Multiwordcnt {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
Job myJob = new Job(conf, "Multiwordcnt");
String[] userargs = new GenericOptionsParser(conf, args).getRemainingArgs();
myJob.setJarByClass(Multiwordcnt.class);
myJob.setMapperClass(MyMapper.class);
myJob.setReducerClass(MyReducer.class);
myJob.setMapOutputKeyClass(Text.class);
myJob.setMapOutputValueClass(IntWritable.class);
myJob.setOutputKeyClass(Text.class);
myJob.setOutputValueClass(IntWritable.class);
myJob.setInputFormatClass(TextInputFormat.class);
myJob.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(myJob, new Path(userargs[0]));
FileOutputFormat.setOutputPath(myJob, new Path(userargs[1]));
System.exit(myJob.waitForCompletion(true) ? 0 : 1 );
}
public static class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
Text emitkey = new Text();
IntWritable emitvalue = new IntWritable(1);
public void map(LongWritable key , Text value, Context context) throws IOException, InterruptedException {
String filePathString = ((FileSplit) context.getInputSplit()).getPath().toString();
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()){
String filepathword = filePathString + "*" + tokenizer.nextToken();
emitkey.set(filepathword);
context.write(emitkey, emitvalue);
}
}
}
public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
Text emitkey = new Text();
IntWritable emitvalue = new IntWritable();
private MultipleOutputs<Text,IntWritable> multipleoutputs;
public void setup(Context context) throws IOException, InterruptedException {
multipleoutputs = new MultipleOutputs<Text,IntWritable>(context);
}
public void reduce(Text key , Iterable <IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values){
sum = sum + value.get();
}
String pathandword = key.toString();
String[] splitted = pathandword.split("\\*");
String path = splitted[0];
String word = splitted[1];
emitkey.set(word);
emitvalue.set(sum);
System.out.println("word:" + word + "\t" + "sum:" + sum + "\t" + "path: " + path);
multipleoutputs.write(emitkey,emitvalue , path);
}
public void cleanup(Context context) throws IOException, InterruptedException {
multipleoutputs.close();
}
}
}
循环while
被评估为cin
,bool
将读取字符(将跳过空格),直到找到新行,这将触发要设置的某些标志cin
,所以在下一次迭代false
将被评估为cin
并且您的循环将停止。