https://drive.google.com/a/navasotaisd.org/file/d/0B3eMFMufj6uVaVNpR0JYNnV4OTQ/view
Okay, so the problem above asks that you read in a file with a message and, using and x, y coordinate system, find the characters being read in and print out the character of that index value. I honestly have tried multiple solutions with making and array of arraylists, a arraylist of arraylists and many other failed data structures. All I need to know, is how would go about reading in the message so that I can search for it?
File f = new File("cipher.in");
f.createNewFile();
Scanner scan = new Scanner(f);
int numOfLines = scan.nextInt();
scan.nextLine();
ArrayList<Character> list = new ArrayList();
String code = "";
for (int i = 0; i < numOfLines; i++) {
code = scan.nextLine();
for (int j = 0; j < code.length(); j++) {
list.add(code.charAt(j));
}
}
int index = 0;
char[][] matrix = new char[(int)(list.size())][(int)(list.size())];
for (int r = 0; r < matrix.length; r++) {
for (int c = 0; c < matrix[r].length; c++) {
matrix[r][c] = list.get(index);
index++;
if(index>=list.size())
index--;
}
}
Sorry if this problem is a bit long. It's for my class I need to turn this problem in to be able to make a 100 in the gradebook. I'm just utterly stuck and frustrated.
Try to use a hash table to store the data. You will be able to search for it later on.
The key fits quite nicely into a two-dimensional charcter array (char[][]). I would consider reading the first line (which specifies the number of lines on the key (rows of the array), and then construct the array. You have a constraint defined that a row can be no longer than 100 characters long so you can now define the complete "map".
After that i would read each line of the key, use an operator as charAt(index) and fill the map.
From there you have a very convenient structure to lookup the messages in the next part of the assignment.
Try this out , this is you code with changes and comments so that you can understand the changes and the way this code works based on the instruction in your link, I did not try to compile it, so if it has any compilation errors try to fix them. I kept your code and commented out the items that are not needed so that you can look at the differences,
File f = new File("cipher.in");
//f.createNewFile(); //* you are overwriting the file here
Scanner scan = new Scanner(f);
int numOfLines = scan.nextInt();
//str = scan.nextLine(); //* you just skipped one line from the numOfLInes
//ArrayList<Character> list = new ArrayList(); //* this does not help, you need to index into the line number, char index
TreeMap charMap = new TreeMap(); //* use this to map the line number to a char array
String code = "";
for (int i = 0; i < numOfLines; i++) {
strubg code = scan.nextLine();
charMap.put(i, code.toCharArray()); //* map the line number with the char array of each line
//for (int j = 0; j < code.length(); j++) {
// list.add(code.charAt(j));
//}
}
int numOfMessageLines = scan.nextInt(); //* get the number of message lines next
for (int i = 0; i < numOfMessageLines; i++) {
string str = scan.nextLine();
string[] pairs = str.split(" "); //* each line has several key pairs for line number char number seprated by spaces
ArrayList<char> list = new ArrayList(); //* this does not help, you need to index into the line number, char index
for(int j=0; j<pairs.length; j++)
{
string[] st = pairs[j].trim().split(","); //* example 2,13 indicate line 2 character 13 non zero indexed
int lineNum = Integer.parse(st[0]) - 1; //* zero indexed line number since we stored the lines in zero index map
int charNum = Integer.parse(st[1]) - 1; //* zero indexed char number since we stored the char array in zero indexed array
char[] chars = charMap.get(lineNum); //* get the char array for this line number
char c = chars[charNum]; //* get the character for the first message
list.add(c);
}
String message = new String(list.toArray()); //* construct the message from the char array
System.out.println(message);
}
//int index = 0;
//char[][] matrix = new char[(int)(list.size())][(int)(list.size())];
//for (int r = 0; r < matrix.length; r++) {
// for (int c = 0; c < matrix[r].length; c++) {
// matrix[r][c] = list.get(index);
// index++;
// if(index>=list.size())
// index--;
// }
//}
Related
I was working through a project and I have to use charAt to continuously add elements of an array from a text file to a new array that i would have specified. The size of the array differs depending on the text file being used so it is best to assume that the contents of the file are unknown, however i will provide an example.
I keep on getting a "StringIndexOutOfBoundException" when i run my code and i am not sure why, or how to fix it.
What the code should be doing is taking the user input to get the exact text file location, then it will be reading that line by line and adding that to a new array. The first two lines of the text file array are the array row and column size.
my code is as follows:
public static void main(String[] args) throws FileNotFoundException
{
System.out.println("Enter the location of the board file using the FULL PATH NAME.");
Scanner input = new Scanner(System.in);
String n = input.nextLine();
input.close();
File a = new File(n);
Scanner sc = new Scanner(a);
int row = sc.nextInt();
int col = sc.nextInt();
char[][] board = new char[row][col];
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
sc.close();
GridGame game = new GridGame (row, col, board);
game.playGame();
An example input text file:
10 10
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
TWWWWWWWWW
The issue you are facing is because a Java array has 0-based index i.e. the index of the first element is 0 and that of the last element is array.length - 1. Therefore, your loop with the variable as the index of the array should not go beyond array.length - 1. Your terminating condition, numRow < row+1 is taking the value of numRow up to the length of the array instead of array.length - 1.
Replace
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
with
for (int r = 0; r < row && sc.hasNextLine(); r++) {
board[r] = sc.nextLine().toCharArray();
}
The other concept you need to understand is a 2-D array in Java an array of arrays i.e. board[0] should hold the array of characters from the first line of the file, board[1] should hold the array of characters from the second line of the file and so on. Now, if you want to access the 4th character of the 3rd line from the file, you can access it as board[2][3].
The last but not the least is regarding closing the Scanner for System.in. You should never close this Scanner because it also closes the System.in. So, you should remove the line, input.close() from your code.
Update
You can write the above mentioned single loop as a nested loop as well but it is unnecessary.
for (int r = 0; r < row && sc.hasNextLine(); r++) {
char[] lineChars = sc.nextLine().toCharArray();
for(int c = 0; c < col; c++) {
board[r][c] = lineChars [c];
}
}
You need a nested loop in order to access/process individual characters but to store/access/process each row of a 2-D array, you do not need a nested loop. As I have already mentioned, a 2-D array is an array of 1-D arrays and therefore to access each of these 1-D arrays (not individual elements inside these 1-D arrays), you need a single loop, not a nested loop.
I am trying to get this code to read in a text file and then populate a 15x15 grid with the numbers from the file. What it is doing is only populating the grid with 0's. I am not sure how to fix it, but I think the issue is with how I am trying to use list.indexOf() in the loop.
I have tried switching to use list.get(i) or using j, which has not worked the way I need it to.
public Grid(String fileName) throws FileNotFoundException {
//reading file using scanner
Scanner sc = new Scanner(new File(fileName));
//first number is the dimension for rows
this.rows = sc.nextInt();
//since it is square matrix second dimension is same as first
this.cols = this.rows;
grid = new boolean[rows][cols];
String longNumber = sc.next();
List<Integer> list = new ArrayList<>();
for(char ch : longNumber.toCharArray()) {
list.add( Integer.valueOf(String.valueOf(ch)));
}
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++) {
//reading from file 1 and 0 if 1 then store true else store false in grid
if (list.indexOf(i) == 1)
grid[i][j] = true;
else
grid[i][j] = false;
}
}
I am getting an output showing a 15x15 block of 0's, instead of the 1's and 0's that are being read in from the text file. The text file should be read in and displayed (along with a count of blobs or clumps of 1's), but this is not happening. If you need the rest of the code, please let me know. I am required to read in a file, which contains an int (15) which is used to make the grid, and then 15 lines of 1's and 0's, which should be displayed in the same way when the program works properly.
Why are you converting it into a List<Integer>? You can simply work with String that you got from the file.
For each row, you'll have to get a String and then for each of such a String you can do charAt() to check what is the character there and store true or false in grid accordingly.
The code will look something like this:
this.rows = sc.nextInt();
//since it is square matrix second dimension is same as first
this.cols = this.rows;
grid = new boolean[rows][cols];
for (int i = 0; i < rows; i++) {
String longNumber = sc.next();
for (int j = 0; j < cols; j++) {
//reading from file 1 and 0 if 1 then store true else store false in grid
grid[i][j] = (longNumber.charAt(j) == 1);
}
}
Notice that I've placed String longNumber = sc.next() in the outer loop.
HTH
Im trying to scan a file and create a 1D array for each line, then immediately following the creation of that array copy into the first row of a 2D array. I've gotten my code to work for only the first row of the file. It won't move onto the next line. it copies the same line as it traverses the whole 2d array. i know that happens because the counter for the scanning the next line doesn't increase before it reaches the end of the 2d array. how can i increase the counter for scanning the next line? heres my code: (tempString is the 1D array already created before this loop)
for(int i = 0; i < 7; i++){
tempString = scnr.nextLine().split(" ");
//add lines to 2d array
for(int r = 0; r < 7; r++){
int x = 0; //moves along each element in tempString
for(int c = 0; c < tempString.length; c++){
temp[r][c] = Double.parseDouble(tempString[x]);
x++;
}
}
}
You have 3 loops, but you only need two. Each input row read from the file will become a row of the 2-D array :
for(int r = 0; r < 7; r++){
tempString = scnr.nextLine().split(" ");
temp[r] = new double[tempString.length];
for(int c = 0; c < tempString.length; c++){
temp[r][c] = Double.parseDouble(tempString[c]);
}
}
I am not quite sure with what exactly you need. But what I have derived from the question is that you have a file and you need to split it in a 2D array, in which the columns should contain the individual items within each line and each row should be in a new line.
My recommendation is to use ArrayList which will handle the dynamic lengths for you.
See the below example:
Say I have a file 'text.txt' which contains some data like this
abc def ghi
jhl mnop qrs uv
wx yz
Then here is a program which forms a 2D array, first dimension containing each row and the second dimension containing tokens from each line.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Split {
public static void main(String args[]){
ArrayList<ArrayList<String>> columns = new ArrayList<ArrayList<String>>();
columns.add(new ArrayList<String>());//Col 1
columns.add(new ArrayList<String>());//Col 2
columns.add(new ArrayList<String>());//Col 3
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader("src\\text.txt"));
String sCurrentLine;
int j=0;
while ((sCurrentLine = br.readLine()) != null) {
String sLine[] = sCurrentLine .split(" ");
for(int i = 0; i < sLine.length; i++)
{
columns.get(j).add(sLine[i]);
}
j++;
}
for(ArrayList<String> line:columns){
for(String tokens:line)
System.out.println(tokens);
System.out.println();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
If this is not what you need, please try to elaborate your question further if possible with examples.
Please note that I'm using spaces (" ") to split the tokens, you can replace it by anything that you are using.
I hope it helps :)
i have generated a pace of code that gets 4 inputs and calculates the square roots of all of them.
int i;
System.out.print("print numbers here:");
int[] arr = new int[4];
Scanner in = new Scanner(System.in);
for (i = 0; i < arr.length; i++ ){
arr[i] = in.nextInt();
}
for (i = arr.length; i > 0; --i){
double s =Math.sqrt(arr[i-1]);
System.out.println(s);
}
here is the code from main method but one important part that i still need to add is to get user inputs with spaces and line breaks. So, for instance
1427 0
876652098643267843
5276538
1427 is first num, 0 the second and etc.. i am new to java and programming and i don't have any idea please help if you can.
thanks in advance!!
Replace your nextInt() call with next(). This will retrieve the next word, with whitespace characters as seperators (newlines and spaces). This will allow for any number of spaces, empty lines etc.
Example:
System.out.print("print numbers here:");
int[] arr = new int[4];
Scanner in = new Scanner(System.in);
for (int i = 0; i < arr.length; i++){
int num;
try {
num = Integer.parseInt(in.next()); // get input
} catch (NumberFormatException e) {
// invalid number
}
arr[i] = num;
}
for (int i = arr.length; i > 0; i--) {
double s = Math.sqrt(arr[i-1]);
System.out.println(s);
} // this is printing the square roots in reverse order, you may want to change
// that to avoid confusion
If you want to split the answer by white space characters (spaces and line breaks), try using the .split function present in Java. In your case, you would take the input received from the user as a String, then do this:
String[] inputVariables = string.split("\\s");
(note that \s represents all white space characters and "string" is your input received)
Now you have a String array of the input received from the user. Then you can use Integer.parseInt on each String to convert them from Strings to ints, and you now have your four integers ready to square-rootify.
you can try something like this
for (i = 0; i < arr.length; i++ ){
try{
String []nos = in.nextLine().split("\\s+");
if(nos.length > 0)
{
for(String no:nos)
arr[i] = Integer.parseInt(no);
}else{
arr[i] = Integer.parseInt(in.nextLine());
}
}catch(Exception e){
i--;
}
}
I've been working on a Java lab that wants us to have the user enter two digits up to 50 digits long and add them together. I've successfully been able to complete everything except for when the two arrays have a different length. I've been toying around with the code for a while, but I keep coming up short. Can anyone look at the code for this and have any suggestions? Thanks!
int[] number1 = new int[input1.length()];
int[] number2 = new int[input2.length()];
int[] answer = new int[input1.length()];
if(number1.length > number2.length){
number2 = new int[number1.length];
for(int i = 0; i < number2.length - number1.length; i++){
number2[i] = 0;
}
}
if(number2.length > number1.length){
number1 = new int[number2.length];
for(int i = 0; i < number1.length - number2.length; i++){
number1[i] = 0;
}
}
Whenever I add, say 120 and 12, it says there's an Array out of bounds error.
First thing you need to do is get the numbers into an int array. Do that by Splitting string to char array. Then convert to int array. Then add.
String input1 = scanner.nextLine().trim(); <-- get input as String
String input2 = scanner.nextLine().trim();
char[] array1 = input1.toCharArray(); <-- split to char array
char[] array2 = input2.toCharArray();
// convert to int array
int[] intArray1 = new int[array1.length]; <-- declare int array
int[] intArray2 = new int[array2.length];
for (int i = 0; i < array1.length; i++){
intArray1[i] = Integer.parseInt(String.valueOf(array1[i])); <-- convert to int
}
for (int i = 0; i < array2.legnth; i++){
intArray2[i] = Integer.parseInt(String.valueOf(array2[i]));
}
// check which one is larger and add to that one
if (intArray1.length > intArray2.length){
for (int i = 0; i < intArray2.length; i++){
intArray1[i] += intArray2[i]; <-- add values
}
System.out.println(Arrays.toString(intArray1); <-- print largest
} else {
for (int i = 0; i < intArray1.length; i++){
intArray2[i] += intArray1[i];
}
System.out.println(Arrays.toString(intArray2);
}
If you want to get the number representation printed instead of an array, instead of the System.out.println(), use this
StringBuilder sb = new StringBuilder();
for (int i : intArray1){
sb.append(String.valueOf(i));
}
System.out.println(sb.toString());
So 123 and 12 will print out 233
My understanding of your code is, you try to pre-append (push from head) 0s to the shorter array. Look at the first if-block. The length of number1 is larger than what of number2. Thus, number2.length - number1.length is negtive. Then, in the for loop, i < number2.length - number1.length is always ture. (I am not familiar with java. I guess array's length is an integer.) And you still have to copy the rest of array.
The correct code should be,
if(number1.length > number2.length) {
int[] number3 = new int[number1.length];
for(int i = 0; i < number1.length - number2.length; ++i) {
number3[i] = 0;
}
for(int i = 0; i < number2.length; ++i) {
number3[i + number1.length - number2.length] = number2[i];
}
number2 = number3;
}
BTW, the second if-block should be changed in a similar way. Perhaps, java provides an API link insert(0, 0) for array object. It will be easier to implement.