I want to be able to read in 20 random names from the file and put them into a new file. How do i go about this?
public class Assignment2 {
public static void main(String[] args) throws IOException
{
// Read in the file into a list of strings
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
//BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
List<String> lines = new ArrayList<String>();
String line = reader.readLine();
while( line != null ) {
lines.add(line);
line = reader.readLine();
}
// Choose a random one from the list
Random r = new Random();
for (int i = 0; i < 20; i++)
{
int rowNum = r.nextInt(lines.size ());
System.out.println(lines.get(rowNum));
}
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter("randomNames.txt"))) {
Random random = new Random();
for (int i = 0; i < 20; i++) {
int rowNum = random.nextInt(lines.size());
writer.write(lines.get(rowNum));
writer.newLine();
}
}
If you need to check if some number was already used, add it to a set:
try (BufferedWriter writer = new BufferedWriter(new FileWriter("randomNames.txt"))) {
Set<Integer> usedNumbers = new HashSet<Integer>(20);
Random random = new Random();
int addedCount = 0;
while (addedCount < 20) {
int rowNum = random.nextInt(lines.size());
if (usedNumbers.add(rowNum)) {
writer.write(lines.get(rowNum));
writer.newLine();
addedCount++;
}
}
}
To check if there is another name with same first character:
private static void containsNameWithSameFirstCharacter(Collection<String> names, String name) {
for (String anotherName : names) {
if (anotherName.charAt(0) == name.charAt(0)) {
return true;
}
}
return false;
}
Then you do:
Random random = new Random();
Set<String> usedNames = new HashSet<String>(20);
while (usedNames.size() < 20) {
int rowNum = random.nextInt(lines.size());
String name = lines.get(rowNum);
if (!containsNameWithSameFirstCharacter(usedNames, name)) {
usedNames.add(name);
writer.write(name);
writer.newLine();
}
}
Related
Making a hangman style of game
I have the random word now. How do I replace the letters of the word with an asterix * so that when the program starts the word is shown as *.
I assume that when someone inputs a letter for the hangman game you get the index of that character in the word and then replace the corresponding *.
public class JavaApplication10 {
public static String[] wordArray = new String[1];
public static String file_dir = "Animals.txt";
public static String selectedWord = "";
public static char[] wordCharacter = new char[1];
Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException {
wordArray = get_word(file_dir);
selectedWord = select_word(wordArray);
System.out.println(selectedWord);
}
public static String[] get_word(String file_dir) throws IOException {
FileReader fileReader = new FileReader(file_dir);
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
return lines.toArray(new String[lines.size()]);
}
public static String select_word(String[] wordArray) {
Random rand = new Random();
int lines = Math.abs(rand.nextInt(wordArray.length)- 1);
return wordArray[lines];
}
}
If you know how many lines are there you could use Random method in java with a specific range to pick out a line at random.
Then you could read the file line-by-line till you reach that random line and print it.
// Open the file
FileInputStream fstream = new FileInputStream("testfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int counter=0;
//While-loop -> Read File Line By Line till the end of file
//And will also terminate when the required line is printed
while ((strLine = br.readLine()) != null && counter!=randomValue){
counter++;
//You need to set randomValue using the Random method as suggested
if(counter==randomValue)
// Print the content on the console
System.out.println (strLine+"\n");
}
//Close the input stream
br.close();
Assuming Java 8:
// Loading ...
Random R = new Random(System.currentTimeMillis());
List<String> animals = Files.readAllLines(Paths.get(path));
// ...
// When using
String randomAnimal = animals.get(R.nextInt(animals.size()));
Answer of your first question :
First you have to get the total number of lines
Then you have to generate a random number between 1 and that total number.
Finally, get the required word
try {
InputStream is = new BufferedInputStream(new FileInputStream("D:\\test.txt"));
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
int noOfLines = count+1;
System.out.println(noOfLines);
Random random = new Random();
int randomInt = random.nextInt(noOfLines);
FileReader fr = new FileReader("D:\\test.txt");
BufferedReader bufferedReader =
new BufferedReader(fr);
String line = null;
int counter =1;
while((line = bufferedReader.readLine()) != null) {
if(counter == randomInt)
{
System.out.println(line); // This the word you want
}
counter++;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally {
//is.close();
}
I am trying to create a program which would replace random number of characters at random position with "*". Star is letter used in main program and it is replaced with "." a wildcard to matches any possible result.
So far I manage to create the code you see bellow. It replaces exactly 1 character of specific word.
Any help from here on now would be much appreciated.
EXAMPLE:
Input word: MOUSE
RANDOM GENERATOR for how much characters to replace: 3
RANDOM GENERATOR at which places to replace: 1, 3, 5
RESULT: *O*S*
public class random_2 {
public static void main(String[] args) {
String test;
int dolzina = 0;
String outputFile = "random_2.txt";
ArrayList<String> list = new ArrayList();
try {
File file = new File("random1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String vrstica;
while ((vrstica = bufferedReader.readLine()) != null) {
list.add(vrstica);
// dolzina=list.size();
// System.out.println(dolzina);
}
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out = new PrintWriter(fileWriter);
for (int idx = 0; idx <= list.size(); ++idx) {
test=list.get(idx);
dolzina=test.length();
Random rGenerator = new Random();
for (int i = 0; i<= dolzina; ++i) {
int randomInt = rGenerator.nextInt(dolzina);
StringBuilder beseda = new StringBuilder(test);
beseda.setCharAt(randomInt, '*');
System.out.println(beseda);
dolzina=0;
}}
System.out.println("Done.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Modified your code and its working:
try {
File file = new File("random1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String vrstica = bufferedReader.readLine();
while (vrstica != null) {
list.add(vrstica);
vrstica = bufferedReader.readLine();
// dolzina=list.size();
// System.out.println(dolzina);
}
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out = new PrintWriter(fileWriter);
for (int idx = 0; idx < list.size(); ++idx) {
test = list.get(idx);
dolzina = test.length();
Random rGenerator = new Random();
StringBuilder beseda = new StringBuilder(test);
for (int i = 0; i < dolzina; ++i) {
int randomInt = rGenerator.nextInt(dolzina);
beseda.setCharAt(randomInt, '*');
System.out.println(beseda);
}
out.print(beseda);
out.close();
}
you can try something like this:
String mask(String s, int charsToMask){
if(s.length() < charsToMask) throw new IllegalArgumentException();
List<Integer> shuffle = new ArrayList<>(s.length())
for (int i = 0; i < s.length(); i++) {
shuffle.add(i, i);
}
Collections.shuffle(shuffle);
StringBuilder sb = new StringBuilder(s)
for (int i = 0; i < charsToMask; i++) {
sb.setCharAt(shuffle.get(i).intValue(), (char)'*')
}
return sb.toString()
}
print mask("MOUSE", 3)
I am trying to add almost 2lac lines in particular txt file(actually conf file) by java program. But it takes almost 112 min when number is only 189000!
I write following code for that
import java.io.*;
public class Fileshandling_example {
static long s1;
static long e1;
static long e2;
static Fileshandling_example fhe= new Fileshandling_example();
public static void main(String args[]) {
try {
s1 = System.nanoTime();
File file1 = new File("\example\mandar.txt");
LineNumberReader lnr1 = new LineNumberReader(new FileReader(file1));
BufferedReader br1 = new BufferedReader(new FileReader(file1));
lnr1.skip(Long.MAX_VALUE);
int a = 1;
StringBuffer sb1 = new StringBuffer("[stations]");
String sCurrentline1 = br1.readLine();
while ((sCurrentline1 = br1.readLine()) != null) {
a++;
if (sCurrentline1.contentEquals(sb1) == true) {
int count = a;
int arraycount = 100000;
for(int i =0; i< (arraycount+1); i++){
if(0 == (i%10000)){
e2 = System.nanoTime();
System.out.println("Time = "+(e2-s1));
}
String abc ="extern => 00"+(1000 + (arraycount-i))+",1,Wait(0.05)";
fhe.insertintoExtensions(file1, (count+1),abc);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
e1 = System.nanoTime();
System.out.println("Time = "+(e1-s1));
}
public void insertintoExtensions(File inFile1, int lineno, String s1)throws Exception {
File outFile1 = new File("\example\111.tmp");
FileInputStream fis = new FileInputStream(inFile1);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
FileOutputStream fos = new FileOutputStream(outFile1);
PrintWriter out = new PrintWriter(fos);
String thisLine = "";
int i =1;
while ((thisLine = in.readLine()) != null) {
if(i == lineno) out.println(s1);
out.println(thisLine);
i++;
}
out.flush();
out.close();
in.close();
inFile1.delete();
outFile1.renameTo(inFile1);
}
}
Can any one help me where i get wrong?
I asked similar question coderanch but here i get clue very fast so i ask here also.
Sorry for that (cross forum asking).
Thanks.
You are loop 100,000 times for every '[stations]' found on "\example\mandar.txt":
if (sCurrentline1.contentEquals(sb1) == true) {
int count = a;
int arraycount = 100000;
for(int i =0; i< (arraycount+1); i++){
and call fhe.insertintoExtensions which loops "\example\mandar.txt" again to copy or the content of the line or the content of s1 parameter until the actual line number is reached:
while ((thisLine = in.readLine()) != null) {
if(i == lineno) out.println(s1);
out.println(thisLine);
i++;
}
Try to improve you code and use BufferedWriter instead of PrintWriter.
I'm trying to read a csv file into either an ArrayList or a String [][] array. In this I'm trying to read it into a list and then form the list, using a tokenizer, into an array. The csv file have 7 columns (A - G) and 961 rows (1-961). My for loop for the 2D array keeps returning a null pointer, but I think it should be working..
public class FoodFacts
{
private static BufferedReader textIn;
private static BufferedReader foodFacts;
static int numberOfLines = 0;
static String [][] foodArray;
public static String aFact;
static int NUM_COL = 7;
static int NUM_ROW = 961;
// Make a random number to pull a line
static Random r = new Random();
public static void main(String[] args)
{
try
{
textIn = new BufferedReader(new InputStreamReader(System.in));
foodFacts= new BufferedReader(new FileReader("foodfacts.csv"));
Scanner factFile = new Scanner(foodFacts);
List<String> facts = new ArrayList<String>();
String fact;
System.out.println("Please type in the food you wish to know about.");
String request = textIn.readLine();
while ( factFile.hasNextLine()){
fact = factFile.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",");
//facts.add(fact);
numberOfLines++;
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
for (int i = 0; i < NUM_ROW ; i++){
foodArray [j][i]= st2.nextToken(); //NULL POINTER HERE
System.out.println(foodArray[j][i]);
}
}
}
}
}
catch (IOException e)
{
System.out.println ("Error, problem reading text file!");
e.printStackTrace();
}
}
}
Initialize your foodArray as foodArray = new String[NUM_ROW][NUM_COL]; before using it.
Also, there is no need for inner for loop as you are reading one row at a time.
use numberOfLines as row:
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",") ;
//facts.add(fact);
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
foodArray [numberOfLines][j]= st2.nextToken();
System.out.println(foodArray[numberOfLines][i]);
}
}
numberOfLines++;
}
Alternatively, I think you can use split to get all columns as once e.g.
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
foodArray [numberOfLines++] = fact.split(",");
}
One question: Is there any specific purpose for declaring all variables as static class variables? Most of them fit as local variable inside the method e.g. numberOfLines?
You can use this String [][] foodArray = csvreadString(filename); method. It actually reads the file twice, but I don't know how to get the csv dimension without reading the data (you need the dimension in order to initialize the array), and this is very fast in comparison to other methods that I tried.
static public class PairInt {
int rows = 0;
int columns = 0;
}
static PairInt getCsvSize(String filename) throws Throwable {
PairInt csvSize = new PairInt();
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
String line;
while ((line = reader.readLine()) != null) {
if (csvSize.columns == 0) {
csvSize.columns = line.split(",").length;
}
csvSize.rows++;
}
reader.close();
return csvSize;
}
static String[][] csvreadString(String filename) throws Throwable {
PairInt csvSize = getCsvSize(filename);
String[][] data = new String[csvSize.rows][csvSize.columns];
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
for (int i = 0; i < csvSize.rows; i++) {
data[i] = reader.readLine().split(",");
}
return data;
}
I need to read a list of numbers in a file and store it into a 2d array.
This is what I have so far. How would I go about achieving this goal?
//this is only part of my code
public class RainFall
{
double[][] precip;
public RainFall()
{
precip = new double [5][12];
}
public void readFile(BufferedReader infile) throws IOException
{
FileInputStream infile = new FileInputStream("numbers.dat");
BufferedReader br = new BufferedReader(new InputStreamReader(infile));
String[][] myarray = new String[5][12];
while (infile.readLine() != null)
{
for (int j = 0; j < 5; j++)
{
for (int i = 0; i < 12; i++)
{
myarray[j][i] = infile.readLine();
}
}
}
infile.close();
}
numbers.dat is 60 lines of:
1.01
0.03
2.14
0.47
//Is each number on a new line? You're very close, I added a few lines below.
public class RainFall
{
double[][] precip;
public RainFall()
{
precip = new double [5][12];
}
public void readFile(BufferedReader infile) throws IOException
{
//FileInputStream infile = new FileInputStream("numbers.dat");
BufferedReader br = new BufferedReader(new FileReader("numbers.dat"));
String line = "";
String[][] myarray = new String[5][12];
while ((line = br.readLine()) != null)
{
double num = Double.parseDouble(line.trim());
for (int j = 0; j < 5; j++)
{
for (int i = 0; i < 12; i++)
{
precip[j][i] = num;
}
}
}
br.close();
}
Instead of
String[][] myarray = new String[5][12];
use
double[][] myarray = new double[5][12];
Then sub this into the loop:
myarray[j][i] = Double.parseDouble(infile.readLine());