Java 从未知大小的输入读取数据子集:使用特定语法的内存使用。(水库取样)

Java 从未知大小的输入读取数据子集:使用特定语法的内存使用。(水库取样),java,memory,sampling,Java,Memory,Sampling,写这封信: N = args[1].split("\\s+").length; 对于命令行参数,如:echo“abcdefghi”| javasubset 3,这是否会像我使用.split()将“abcdefghi”字符串解析为字符串数组那样消耗类似的内存 我的任务说明(作为一项挑战),学生(me)可以尝试从N个字符串(上面的N=9,a到I)输入中随机均匀地显示K个字符串(上面的命令行中的K=3),同时消耗与K成比例的内存,而不是N。 这就是我想要做的 编辑:mvp的答案帮助很大。现在更好地理

写这封信:

N = args[1].split("\\s+").length;
对于命令行参数,如:
echo“abcdefghi”| javasubset 3
,这是否会像我使用
.split()
“abcdefghi”
字符串解析为字符串数组那样消耗类似的内存

我的任务说明(作为一项挑战),学生(me)可以尝试从N个字符串(上面的N=9,a到I)输入中随机均匀地显示K个字符串(上面的命令行中的K=3),同时消耗与K成比例的内存,而不是N。 这就是我想要做的

编辑:mvp的答案帮助很大。现在更好地理解这个问题

但我觉得我应该补充一点,我只允许使用这个:

private static Scanner Scanner=new Scanner(new BufferedInputStream(System.in),charsetName)


我不能单独使用
Scanner
类,也不能使用
BufferedReader
。考虑到这个限制,我有点不确定如何继续。

是的,它将使用相同的方法,因为
字符串[]
数组是由于
拆分而创建的,即使您没有显式地将其存储在任何地方

我建议您通过以下方式从输入中提取单词:

    import java.util.Scanner;

    public class MyProgram {
        public static void main(String... args) {
            final int K= 3 ;
            String[] words= new String[K] ;
            int wordCount= 0 ;
            int nextWord= 0 ;
            Scanner scanner= new Scanner(System.in) ;
            while( scanner.hasNext() ) {
                String word= scanner.next();
                wordCount++;
                if( nextWord < K ) {
                    words[nextWord]= word ;
                    nextWord++;
                } else {
                    int replacePos= (int)(Math.random()*wordCount) ; 
                    if( replacePos < K ) {
                        words[replacePos]= word ;
                    }
                }
            }
            scanner.close();
            for(String word: words ) {
                System.out.println(word);
            }
        }
    }
  • 创建一个
    列表单词列表
    来存储这3个单词
  • 生成一个介于0和输入长度减1之间的随机数
  • 如果随机数对应的位置是空白,则生成新的随机数,直到该位置不是空白
  • 使用最后一个随机数作为起点,返回输入,搜索空白或输入的开始。这(+1)定义了单词的开头
  • 再次使用相同的随机数作为起点,在输入中继续搜索空白或输入的结尾。这个(-1)定义了一个单词的结尾
  • 如果该单词已在
    单词列表中,则丢弃该单词并从步骤2开始重复
  • 如果没有,请将其添加到列表中
  • 如果列表的大小小于3,也从步骤2重复
  • 打印列表
  • 在此过程中,您在内存中只存储了3个单词(K),而不是9个(N)

    也可以通过以下方式执行扫描:

        import java.util.Scanner;
    
        public class MyProgram {
            public static void main(String... args) {
                final int K= 3 ;
                String[] words= new String[K] ;
                int wordCount= 0 ;
                int nextWord= 0 ;
                Scanner scanner= new Scanner(System.in) ;
                while( scanner.hasNext() ) {
                    String word= scanner.next();
                    wordCount++;
                    if( nextWord < K ) {
                        words[nextWord]= word ;
                        nextWord++;
                    } else {
                        int replacePos= (int)(Math.random()*wordCount) ; 
                        if( replacePos < K ) {
                            words[replacePos]= word ;
                        }
                    }
                }
                scanner.close();
                for(String word: words ) {
                    System.out.println(word);
                }
            }
        }
    
    import java.util.Scanner;
    公共类MyProgram{
    公共静态void main(字符串…参数){
    最终int K=3;
    字符串[]字=新字符串[K];
    int字数=0;
    int nextWord=0;
    扫描仪=新的扫描仪(System.in);
    while(scanner.hasNext()){
    字符串字=scanner.next();
    字数++;
    if(nextWord
    是的,它将使用相同的方法,因为
    字符串[]
    数组是由于
    拆分而创建的,即使您没有显式地将其存储在任何位置

    我建议您通过以下方式从输入中提取单词:

        import java.util.Scanner;
    
        public class MyProgram {
            public static void main(String... args) {
                final int K= 3 ;
                String[] words= new String[K] ;
                int wordCount= 0 ;
                int nextWord= 0 ;
                Scanner scanner= new Scanner(System.in) ;
                while( scanner.hasNext() ) {
                    String word= scanner.next();
                    wordCount++;
                    if( nextWord < K ) {
                        words[nextWord]= word ;
                        nextWord++;
                    } else {
                        int replacePos= (int)(Math.random()*wordCount) ; 
                        if( replacePos < K ) {
                            words[replacePos]= word ;
                        }
                    }
                }
                scanner.close();
                for(String word: words ) {
                    System.out.println(word);
                }
            }
        }
    
  • 创建一个
    列表单词列表
    来存储这3个单词
  • 生成一个介于0和输入长度减1之间的随机数
  • 如果随机数对应的位置是空白,则生成新的随机数,直到该位置不是空白
  • 使用最后一个随机数作为起点,返回输入,搜索空白或输入的开始。这(+1)定义了单词的开头
  • 再次使用相同的随机数作为起点,在输入中继续搜索空白或输入的结尾。这个(-1)定义了一个单词的结尾
  • 如果该单词已在
    单词列表中,则丢弃该单词并从步骤2开始重复
  • 如果没有,请将其添加到列表中
  • 如果列表的大小小于3,也从步骤2重复
  • 打印列表
  • 在此过程中,您在内存中只存储了3个单词(K),而不是9个(N)

    也可以通过以下方式执行扫描:

        import java.util.Scanner;
    
        public class MyProgram {
            public static void main(String... args) {
                final int K= 3 ;
                String[] words= new String[K] ;
                int wordCount= 0 ;
                int nextWord= 0 ;
                Scanner scanner= new Scanner(System.in) ;
                while( scanner.hasNext() ) {
                    String word= scanner.next();
                    wordCount++;
                    if( nextWord < K ) {
                        words[nextWord]= word ;
                        nextWord++;
                    } else {
                        int replacePos= (int)(Math.random()*wordCount) ; 
                        if( replacePos < K ) {
                            words[replacePos]= word ;
                        }
                    }
                }
                scanner.close();
                for(String word: words ) {
                    System.out.println(word);
                }
            }
        }
    
    import java.util.Scanner;
    公共类MyProgram{
    公共静态void main(字符串…参数){
    最终int K=3;
    字符串[]字=新字符串[K];
    int字数=0;
    int nextWord=0;
    扫描仪=新的扫描仪(System.in);
    while(scanner.hasNext()){
    字符串字=scanner.next();
    字数++;
    if(nextWord
    对于长度未知的输入数据流,这可以解决(也就是说,我们只在EOF上停止,不关心N是什么),并且将使用与K成比例的内存

    首先,让我们求解K=1。若我们开始读取输入流,我们应该假设第一项(在你们的例子中是A)应该是我们的答案——因为若并没有输入,那个就必须是它。当我们读第二个项目时,我们应该考虑把它作为我们的答案,而不是以概率<代码> 1/2 /代码>。什么时候