编程 - 使用C ++的原理和实践 - 第3章尝试本练习 - 重复单词检测

时间:2015-07-25 17:10:57

标签: c++

您好我跟随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;

        }


}

我不明白为什么一旦重复两个单词,程序就不会打印到屏幕上,只有当你按下回车键时它才会重复打印。如果有人能够解释这一点,我将非常感谢!

2 个答案:

答案 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被评估为cinbool将读取字符(将跳过空格),直到找到新行,这将触发要设置的某些标志cin,所以在下一次迭代false将被评估为cin并且您的循环将停止。