This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 3 months ago.
I am currently learning Java and received the following task, that I cannot seem to solve:
"Create a Java program that prints one random poem of 5 lines in the console. The poems must be read from a text file."
I have copied 10 different poems inside a text file, all written underneath each other. I managed to make the program print out the very first poem (first 5 lines) in the console, but first of all, I am not sure if it's the correct way to do such, and I don't know how to make the program print out one random poem (5 lines that belong together) each time I run it.
Here is the farthest I could get:
public static void main(String[] args) throws IOException {
File file = new File("src/main/java/org/example/text.txt");
Scanner scanner = null;
try {
scanner = new Scanner(file);
int i = 0;
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (i < 5) {
i++;
System.out.println(line);
}
}
} catch (Exception e) {
}
}
You can try
private static final int POEM_LINES_LENGTH = 5;
public static void main(String[] args) throws IOException
{
// The file
File file = new File("src/main/java/org/example/text.txt");
// Get all the lines into a single list
List<String> lines = Files.readAllLines(Paths.get(file.getAbsolutePath()));
// Get a random poem and point at the end.
int poemFinish = new Random().nextInt(lines.size() / POEM_LINES_LENGTH) * POEM_LINES_LENGTH;
// Point to the be start
int start = poemFinish - POEM_LINES_LENGTH;
// Create a sublist with the start and finish indexes.
for (String line : lines.subList(start, poemFinish))
System.out.println(line);
}
This will not read the entire file into the memory, hence large files can also be read.
final int totalPoems = 17;
int skip = new Random().nextInt(totalPoems) * 5;
Path path = Paths.get("file.txt");
BufferedReader reader = Files.newBufferedReader(path);
while(skip-->0){
reader.readLine();
}
for(int i=0; i<5; i++){
System.out.println(reader.readLine());
}
The downside is you have to know how many poems are in the file beforehand. If you don't want to do this you can quickly count the total number of lines/poems only one time.
Related
This question already has answers here:
How to read a specific line using the specific line number from a file in Java?
(19 answers)
Closed 3 years ago.
Im a novice java learner, i have a little problem and i hope you guys can help me out.
i have a Names.txt file that contains a huge amount of random names, each line has an appropriate name
(expl:
jhon
Micheal
Anthony
etc...)
I've been writing a function that randomly choses one of these names:
public static void RandomNameGenerator() throws FileNotFoundException
{
// the File.txt has organized names, meaning that each line contains a name
//the idea here is to get a random int take that number and find a name corresponding to that line number
int txtnumlines = 0; // how many lines the txt file has
Random random = new Random();
Scanner file = new Scanner(new File("Names.txt")); //loads the txt file
while (file.hasNext()) //counts the number of lines
{
file.nextLine();
txtnumlines += 1;
}
int randomintname = random.nextInt(txtnumlines);
// takes a random number, that number will be used to get the name from the txt line
String RandomName = "";
// I'm stuck here :(
}
the problem is i don't know how to continue, more specifically how to extract that name (let's say alex) using the random integers i have that represents a random line
hope my question was clear,
Thank you for helping me out!
Here, you might want to try this:
public static void RandomNameGenerator() throws FileNotFoundException
{
// the File.txt has organized names, meaning that each line contains a name
//the idea here is to get a random int take that number and find a name corresponding to that line number
int txtnumlines = 0; // how many lines the txt file has
Random random = new Random();
Scanner file = new Scanner(new File("Names.txt")); //loads the txt file
Scanner fileReloaded = new Scanner(new File("Names.txt")); //Let's use another one since we can't reset the first scanner once the lines have been counted (I'm not sure tho)
while (file.hasNext()) //counts the number of lines
{
file.nextLine();
txtnumlines += 1;
}
int randomintname = random.nextInt(txtnumlines);
// takes a random number, that number will be used to get the name from the txt line
int i = 0;
String RandomName = "";
while(fileReloaded.hasNext())
{
String aLine = fileReloaded.nextLine();
if (i == randomintname) Randomname = aLine;
i++;
}
// Now you can do whatever you want with the Randomname variable. You might want to lowercase the first letter, however. :p
}
Reading all lines
String[] lines = new Scanner(
MyClass.class.getClassLoader().getResourceAsStream("Names.txt"),
StandardCharsets.UTF_8.name()
).next().split("\\A");
Extract random line
Random random = new Random();
String randomLine = lines[random.nextInt(lines.length)].trim();
I have a .txt file that lists integers in groups like so:
20,15,10,1,2
7,8,9,22,23
11,12,13,9,14
and I want to read in one of those groups randomly and store the integers of that group into an array. How would I go about doing this? Every group has one line of five integers seperated by commas. The only way I could think of doing this is by incrementing a variable in a while loop that would give me the number of lines and then somehow read from one of those lines that is chosen randomly, but I'm not sure how it would read from only one of those lines randomly. Here's the code that I could come up with to sort of explain what I'm thinking:
int line = 0;
Scanner filescan = new Scanner (new File("Coords.txt"));
while (filescan.hasNextLine())
{
line++;
}
Random r = new Random(line);
Now what do I do to make it scan line r and place all of the integers read on line r into a 1-d array?
There is an old answer in StackOverflow about choosing a line randomly. By using the choose() method you can randomly get any line. I take no credit of the answer. If you like my answer upvote the original answer.
String[] numberLine = choose(new File("Coords.txt")).split(",");
int[] numbers = new int[5];
for(int i = 0; i < 5; i++)
numbers[i] = Integer.parseInt(numberLine[i]);
I'm assuming you know how to parse the line and get the integers out (Integer.parseInt, perhaps with a regular expression). If you're sing a scanner, you can specify that in your constructor.
Keep the contents of each line, and use that:
int line = 0;
Scanner filescan = new Scanner (new File("Coords.txt"));
List<String> content = new ArrayList<String>(); // new
while (filescan.hasNextLine())
{
content.add(filescan.next()); // new
line++;
}
Random r = new Random(line);
String numbers = content.get(r.nextInt(content.size()); // new
// Get numbers out of "numbers"
Read lines one by one from the file, store them in a list and generate a random number from the list's size and use it to get the random line.
public static void main(String[] args) throws Exception {
List<String> aList = new ArrayList<String>();
Scanner filescan = new Scanner(new File("Coords.txt"));
while (filescan.hasNextLine()) {
String nxtLn = filescan.nextLine();
//there can be empty lines in your file, ignore them
if (!nxtLn.isEmpty()) {
//add lines to the list
aList.add(nxtLn);
}
}
System.out.println();
Random r = new Random();
int randomIndex=r.nextInt(aList.size());
//get the random line
String line=aList.get(randomIndex);
//make 1 d array
//...
}
Hi I'm in a programming class over the summer and am required to create a program that reads input from a file. The input file includes DNA sequences ATCGAGG etc and the first line in the file states how many pairs of sequences need to be compared. The rest are pairs of sequences. In class we use the Scanner method to input lines from a file, (I read about bufferedReader but we have not covered it in class so not to familiar with it) but am lost on how to write the code on how to compare two lines from the Scanner method simultaneously.
My attempt:
public static void main (String [] args) throws IOException
{
File inFile = new File ("dna.txt");
Scanner sc = new Scanner (inFile);
while (sc.hasNextLine())
{
int pairs = sc.nextLine();
String DNA1 = sc.nextLine();
String DNA2 = sc.nextLine();
comparison(DNA1,DNA2);
}
sc.close();
}
Where the comparison method would take a pair of sequences and output if they had common any common characters. Also how would I proceed to input the next pair, any insight would be helpful.. Just stumped and google confused me even further. Thanks!
EDIT:
Here's the sample input
7
atgcatgcatgc
AtgcgAtgc
GGcaAtt
ggcaatt
GcT
gatt
aaaaaGTCAcccctccccc
GTCAaaaaccccgccccc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gctagtacACCT
gctattacGcct
First why you are doing:
while (sc.hasNextLine())
{
int pairs = sc.nextLine();
While you have pairs only in one line not pairs and two lines of input, but number of lines once? Move reading pairs from that while looop and parse it to int, then it does not matter but you could use it to stop reading lines if you know how many lines are there.
Second:
throws IOException
Might be irrelevant but, really you don't know how to do try catch and let's say skip if you do not care about exceptions?
Comparision, if you read strings then string has method "equals" with which you can compare two strings.
Google will not help you with those problems, you just don't know it all, but if you want to know then search for basic stuff like type in google "string comparision java" and do not think that you can find solution typing "Reading two lines from an input file using Scanner" into google, you have to go step by step and cut problem into smaller pieces, that is the way software devs are doing it.
Ok I have progz that somehow wokrked for me, just finds the lines that have something and then prints them out even if I have part, so it is brute force which is ok for such thing:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class program
{
public static void main (String [] args) throws IOException
{
File inFile = new File ("c:\\dna.txt");
Scanner sc = new Scanner (inFile);
int pairs = Integer.parseInt(sc.nextLine());
for (int i = 0; i< pairs-1; i++)
{
//ok we have 7 pairs so we do not compare everything that is one under another
String DNA1 = sc.nextLine();
String DNA2 = sc.nextLine();
Boolean compareResult = comparison(DNA1,DNA2);
if (compareResult){
System.out.println("found the match in:" + DNA1 + " and " + DNA2) ;
}
}
sc.close();
}
public static Boolean comparison(String dna1, String dna2){
Boolean contains = false;
for (int i = 0; i< dna1.length(); i++)
{
if (dna2.contains(dna1.subSequence(0, i)))
{
contains = true;
break;
}
if (dna2.contains(dna1.subSequence(dna1.length()-i,dna1.length()-1 )))
{
contains = true;
break;
}
}
return contains;
}
}
My current program reads a file and copies it to another directory, but I want it to change one single character to x, which is given by two ints for the number of the line and the number of the character in the line.
For example if int line = 5 and int char = 4, the fourth character in line five is changed to an x, the rest remains.
How can I add this to my program?
import java.io.*;
import java.util.Scanner;
public class copytest {
public static void main(String[] args) throws Exception {
readFile();
}
public static void readFile() throws Exception {
// Location of file to read
File file = new File("Old.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
//System.out.println(line);
writeFile(line);
}
scanner.close();
System.out.println("File Copied");
}
public static void writeFile(String copyText) throws Exception {
String newLine = System.getProperty("line.separator");
// Location of file to output
Writer output = null;
File file = new File("New.txt");
output = new BufferedWriter(new FileWriter(file, true));
output.write(copyText);
output.write(newLine);
output.close();
}
}
Change your loop to:
int i=0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (i == lineNumber) {
if (line.length() >= charNumber) {
line = line.substring(0,charNumber) + wantedChar +
line.substring(charNumber);
}
}
writeFile(line);
i++;
}
Note that it will replace the char only if the line long enogth.
Ran Eldan has answered your Question, but I want to point out a couple of other major problems with your code:
You are violating Java's identifier style rules. Java class names should be "camel case" and the first character should be an uppercase letter; i.e.
public class copytest {
should be
public class CopyTest {
This is not just a random nit-pick. If you ignore these style rules, you are liable to get yourself into problem when one of your class names collides with a member or package name defined by your ... or someone else's code. The errors can be very hard to spot.
And of course, if you flout the style rules, you will get continual flak from other programmers when they need to read your code.
Your writeFile method is horribly inefficient. Each time you call it, you open the file, write a line and close it again. This results in at least 3 system calls for each line written. Syscall overheads are significant.
And in addition to being inefficient, you have the problem of dealing with existing output files when the program is run multiple times.
What you should do is open the file once at the start of the run, and use the same BufferedWriter throughout.
I have looked at all the links and cannot seem to get what I am looking for. I have a text file I need to read in. First the text file format:
3 STL NY Chi //all on one line
STL NY 575 //on its own line
NY Chi 550 //on its own line
STL Chi 225 //on its own line
I need to read the int into an int variable, say we call it count. Then the actual cities on that same line into an array. The next lines need to read into an array to where the mileage is associated with the array, such as [STL NY]=575. I can only use arrays. No hash tables, list, stacks or queues. Here is what I got so far and honestly it isn't much. I could really use some help for I am pretty stumped on the "howto" on this.
import java.io.*;
import java.util.*;
public class P3 {
/**
* #param args the command line arguments
*/
public static int count;
public static void main(String[] args) {
try {
FileInputStream dataFile = new FileInputStream("Data.txt");
//BufferedReader br = new BufferedReader(new InputStreamReader(dataFile));
String line = br.readLine();
}
catch (IOException e) {
System.err.println ("Unable to open file");
System.exit(-1);
}
}
}
I think I'm getting there, but I am getting an error code of: "non-static variable cities cannot be referenced from a static context." I am trying to test my code by printing. Can anyone help me with this printing? I would like to see what is in the arrays to make sure I did it correctly. Here is my code:
package p3;
import java.io.*;
import java.util.*;
class citiesDist {
String cityOne;
String cityTwo;
int miles;
}
class city {
String cityName;
int numberLinks;
citiesDist[] citiesDists;
}
public class P3 {
city[] cities;
void initCity(int len) {
for (int i = 0; i < len; i++) {
cities[i] = new city();
}
}
void initCitiesDist (int index, int len) {
for (int i = 0; i < len; i++) {
cities[index].citiesDists[i] = new citiesDist();
}
}
void parseFile() throws FileNotFoundException, IOException {
FileInputStream fstream = new FileInputStream("Data.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
int numberCities = Integer.parseInt(br.readLine());
cities = new city[numberCities];
initCity(numberCities);
for (int i = 0; i < numberCities; i++) {
String line = br.readLine();
int numberLink = Integer.parseInt(line.split(" ")[1]);
cities[i].cityName = line.split(" ")[0];
cities[i].numberLinks = numberLink;
initCitiesDist (i, numberLink);
for (int j = 0; j < numberLink; j++){
line = br.readLine();
cities[i].citiesDists[j].cityOne = line.split(" ")[0];
cities[i].citiesDists[j].cityTwo = line.split(" ")[1];
cities[i].citiesDists[j].miles = Integer.parseInt(line.split(" ")[2]);
}
}
}
public static void main(String args[]) {
System.out.println("city" + cities.city);
}
}
If you're ever stumped on code, don't think about the programming language; it only serves to further muddle your logic. (Separate the algorithm from the language.) When you have a clear idea of what you want to accomplish, add your language in (insofar as, "how do I accomplish this particular task?").
Ultimate Goal
From your design, your goal is to have a graph relating the distances between each city. It would appear something like this:
[STL][NY] [Chi]
[STL][0] [575][25]
[NY] [575][0] [550]
[Chi][25] [550][0]
This isn't too terribly difficult to accomplish, in terms of the file input and the Scanner class.
First Steps
You have to extract the dimensions of your graph (which is a 3 by 3). This is provided for you in the first line of your input file. Getting an integer from a Scanner with a File in it isn't too difficult, just make sure you have the proper classes imported, as well as the proper error handling (either try...catch or throwing the exception).
Scanner sc = new Scanner(new File("input.txt"));
You'll need two arrays - one for the cities, and one for the distances themselves. We don't know how large they are (you never assume the data in a file, you just assume the form of the data), so we have to get that from the file itself. Luckily, we are given an integer followed by the cities themselves. We will read this integer once and use it in multiple different locations.
String[] cities = new String[sc.nextInt()];
int[][] distances = new int[cities.length][cities.length];
for(int i = 0; i < cities.length; i++) {
// Surely there's a method in Scanner that returns String that reads the _next_ token...
}
The Exercise to the Reader
You now have your data structure set up and ready to go. What you would need to do from here is bridge the gap between the cities array and distances array. Consider the order in which they arrived in the file, and the order in which we're encountering them. You would be well-served with some methodology or way to answer the question, 'Which came first - STL or NY?'
Give it a whirl and see if you can get further.