Есть ли способ использовать класс сканера inputFile.nextLine ()); но выбор будет случайным? [Дубликат]

В $CUDA_HOME/include/host_config.h найдите такие строки (они могут незначительно меняться между разными версиями CUDA):

//...
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9)

#error -- unsupported GNU version! gcc versions later than 4.9 are not supported!

#endif [> __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) <]
//...

Удалите или измените их, соответствующие вашему условию.

Обратите внимание на этот метод является потенциально опасным и может нарушить вашу сборку. Например, gcc 5 использует C ++ 11 по умолчанию, однако это не относится к nvcc с CUDA 7.5. Обходным путем является добавление

--Xcompiler="--std=c++98" для CUDA & lt; = 6.5

или

--std=c++11 для CUDA> = 7.0.

20
задан Fluffy 7 February 2010 в 20:47
поделиться

5 ответов

Вот решение. Взгляните на метод select (), который делает реальную вещь (метод main () неоднократно выполняет функцию select (), чтобы показать, что распределение действительно довольно равномерное).

Идея проста: когда вы читаете первую строчку, у нее есть 100% шанс быть выбранным в качестве результата. Когда вы читаете вторую строчку, у нее есть 50% шанс заменить первую строку в качестве результата. Когда вы читаете 3-ю строчку, у нее есть 33% шанс стать результатом. Четвертая строка имеет 25% и т. Д ....

import java.io.*;
import java.util.*;

public class B {

  public static void main(String[] args) throws FileNotFoundException {
     Map<String,Integer> map = new HashMap<String,Integer>();
     for(int i = 0; i < 1000; ++i)
     {
        String s = choose(new File("g:/temp/a.txt"));
        if(!map.containsKey(s))
           map.put(s, 0);
        map.put(s, map.get(s) + 1);
     }

     System.out.println(map);
  }

  public static String choose(File f) throws FileNotFoundException
  {
     String result = null;
     Random rand = new Random();
     int n = 0;
     for(Scanner sc = new Scanner(f); sc.hasNext(); )
     {
        ++n;
        String line = sc.nextLine();
        if(rand.nextInt(n) == 0)
           result = line;         
     }

     return result;      
  }
}
18
ответ дан Itay Maman 19 August 2018 в 05:13
поделиться
  • 1
    Реализация выборки коллектора – Will 7 February 2010 в 21:32
  • 2
    Удивительно. Никогда не слышал о пробке коллектора. Как насчет того, является ли мой файл MB? Существуют ли какие-либо проблемы с исполнением? Если да, есть ли альтернативы, чтобы избежать полного сканирования файлов? – lorenzo-s 18 May 2012 в 11:23
  • 3
    Правильно ли я и предполагаю, что это для фиксированного n = 1, где n - число «выборок»? Есть ли способ выбрать выбор более одного раза? поскольку это означает, что вы «переплетаете ленту» более одного раза или, по крайней мере, пытаетесь сделать это неэффективно. – Pureferret 1 October 2012 в 14:28

Чтение всего файла, если вы хотите, чтобы только одна строка казалась немного чрезмерной. Следующее должно быть более эффективным:

  1. Используйте RandomAccessFile для поиска случайной позиции байта в файле.
  2. Ищите влево и вправо на следующий ограничитель строки. Пусть L - линия между ними.
  3. С вероятностью (MIN_LINE_LENGTH / L.length) возвращаем L. В противном случае начните с шага 1.

Это вариант отбраковка .

Длина линии включает символ (-ы) линии окончания, поэтому MIN_LINE_LENGTH> = 1. (Тем лучше, если вы знаете более жесткую привязку длины строки).

Стоит отметить, что время выполнения этого алгоритма не зависит от размера файла, а только от длины строки, то есть оно масштабируется намного лучше, чем чтение всего файла.

22
ответ дан Community 19 August 2018 в 05:13
поделиться
  • 1
    Отлично! Если файл будет отбираться повторно, используйте один проход для сбора List<Integer> смещений, которые затем могут быть рандомизированы через Collections.shuffle(). – trashgod 8 February 2010 в 01:08
  • 2
    Это должен быть лучший ответ. – akuz 7 January 2016 в 09:26

Оглядываясь на ответ Итай, похоже, что он читает файл тысячу раз после выборки одной строки кода, тогда как истинная выборка коллектора должна проходить только по «ленте» один раз. Я разработал код для перебора кода один раз с реальной выборкой коллектора на основе этого и различных описаний в Интернете.

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

public class reservoirSampling {

    public static void main(String[] args) throws FileNotFoundException, IOException{
        Sampler mySampler = new Sampler();
        List<String> myList = mySampler.sampler(10);
        for(int index = 0;index<myList.size();index++){
            System.out.println(myList.get(index));
        }
    }
}

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Sampler {

    public Sampler(){}
    public List<String> sampler (int reservoirSize) throws FileNotFoundException, IOException
    {
        String currentLine=null;
        //reservoirList is where our selected lines stored
        List <String> reservoirList= new ArrayList<String>(reservoirSize); 
        // we will use this counter to count the current line number while iterating
        int count=0; 

        Random ra = new Random();
        int randomNumber = 0;
        Scanner sc = new Scanner(new File("Open_source.html")).useDelimiter("\n");
        while (sc.hasNext())
        {
            currentLine = sc.next();
            count ++;
            if (count<=reservoirSize)
            {
                reservoirList.add(currentLine);
            }
            else if ((randomNumber = (int) ra.nextInt(count))<reservoirSize)
            {
                reservoirList.set(randomNumber, currentLine);
            }
        }
        return reservoirList;
    }
}

Основная предпосылка заключается в том, что вы заполните резервуар, а затем вернитесь к нему и заполните случайные линии с вероятностью 1 / ReservoirSize. Надеюсь, это обеспечит более эффективный код. Пожалуйста, дайте мне знать, если это не сработает для вас, поскольку я буквально сбил его через полчаса.

6
ответ дан Pureferret 19 August 2018 в 05:13
поделиться

Либо вы

  1. дважды читаете файл - один раз, чтобы подсчитать количество строк, второй раз, чтобы извлечь случайную строку, или
  2. использовать резервуар выборка
9
ответ дан Will 19 August 2018 в 05:13
поделиться

Используйте BufferedReader и прочитайте строку. Использовать объект java.util.Random для случайного прерывания;)

-1
ответ дан ZeissS 19 August 2018 в 05:13
поделиться
  • 1
    Как обеспечить, чтобы файл не закончился, когда я хочу остановиться? То есть как узнать количество строк в файле? – Fluffy 7 February 2010 в 20:39
  • 2
    Кроме того, я хочу, чтобы вероятность получения каждой отдельной линии была одинаковой. – Fluffy 7 February 2010 в 20:40
  • 3
    @Dinuk, поэтому, если файл меньше остальных, я получаю последнюю строку слишком часто, если файл больше - я получу слишком редко – Fluffy 7 February 2010 в 20:44
  • 4
    Если вы должны прочитать файл дважды, или если все строки имеют равную длину, вы можете рассчитать количество строк из размера файла – ZeissS 7 February 2010 в 20:50
Другие вопросы по тегам:

Похожие вопросы: