Computing terms x terms matrix - java

I am stuck on a problem for a very long time which requires me to compute a terms x terms matrix. So, I have 2 arrays which is keywords and sentences as below:
String[] Keywords = {"Human", "Machine", "Interface", "Application" };
String[] Sentence = {"Human is Machine", "Interface of Robot", "Application on Human"};
Next, I have to tabulate them as shown in the figure below.
Logic:
We put a 0 if the row and column is of the same keyword.
In Human(row) x Machine(column) space, we put 1 because these two
words appear in the same sentence once (that is the first sentence
in the array).
In Human(row) x Interface(column), we put 0 because this two words
doesn't exist together in neither of the sentences.
The search is non case sensitive.
And proceed to the next column and then next row.
This is what I've attempted but somehow something is wrong.
public class Test {
public static int [][] matrix;
public static void main(String[] args) throws Exception {
String[] Keywords = {"Human", "Machine", "Interface", "Application" };
String[] Sentence = {"Human is Machine", "Interface of Robot", "Application on Human"};
int [][] matrix = new int[Keywords.length][Keywords.length]; //initialize matrix
System.out.println(Arrays.toString(Keywords));
System.out.println("\n"+ Arrays.toString(Sentence));
for (int i=0;i<Keywords.length;i++)
{
int count = 0;
for (int q=1;q<Sentence.length;q++)
{
if (Keywords[i].contains(Sentence[q]))
{
matrix[i][q] = count++;
}
}
}
System.out.println(Arrays.deepToString(matrix));
}
}
Any help is appreciated. Thanks!

There are some logical errors in your forloop.
With if (Keywords[i].contains(Sentence[q])) you are checking whether the keyword contains the sentence and not whether the opposite holds.
Another thing is that your matrix is based on the Keywords yet you are using the Sentence iterator to indicate the line.
Correct code would be
for (int i=0;i<Keywords.length-1;i++){
for(int j = i+1; j < Keywords.length; j++){
int count = 0;
for (int q=0;q<Sentence.length;q++){
if(Sentence[q].contains(Keywords[i]) && Sentence[q].contains(Keywords[j])){
count++;
}
}
matrix[i][j] = count;
matrix[j][i] = count;
}
}
This will output your example matrix.

There are several mistakes to your program:
if (Keywords[i].contains(Sentence[q]))
this condition checks whether a sentence is contained in a keyword. You want to check the opposite.
matrix[i][q] = count++;
Why do you use this? You want to set the value of the cell to 1, if you find a match. Simply set the value to 1 instead of using a complicated expression that doesn't even work:
matrix[i][q] = 1;
In general:
Whatever IDE you use should provide a debugger. Learn to use it; there's no way to avoid this anyways, if you want to write working code on a larger scale.

Related

Searching for words in Multi-Dimension Array,Java

I want to search for words in a Word Puzzle in Java.
The search,as stated is in horizontal,vertical and Diagonal.
I created an Array, but I just don't know how to create a String, and search for words in my String. I need to know how can I have a String that keeps all the values of the table, and how can I be able to type a word, and search for it here.
I know that the search of the words is done with indexOf Function,but I don't know how to perform it.
import java.util.Scanner;
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int IntegerPosition;
int IntegerPosition2;
String position="";
String word="";
Scanner s = new Scanner(System.in);
String content="";
String[][] sopa = {
{"X","F","E","K","J","U","I","R","S","H"},
{"Z","H","S","W","E","R","T","G","O","T"},
{"B","R","A","B","F","B","P","M","V","U"},
{"D","W","E","R","O","O","J","L","L","W"},
{"U","T","O","N","I","R","O","B","C","R"},
{"O","P","R","O","V","I","I","K","V","B"},
{"N","I","Q","U","E","N","T","N","S","A"},
{"O","V","U","L","R","O","S","S","O","T"},
{"A","S","A","X","J","T","R","R","I","T"},
{"R","K","M","E","P","U","B","O","T","A"}
};
for (int i = 0; i < sopa[0].length; i++){
for(int j = 0; j < sopa[i].length; j++){
content += sopa[i][j];
}
System.out.println(content);
content = "";
}
System.out.println("Type the word you are looking for");
word = s.next();
for (int i = 0; i < sopa[0].length-1; i++){//t1.length
for(int j = 0; j < sopa[i].length-1; j++){
}
}
System.out.println(content);
content = "";
}
}
First, you should declare what "finding a word" means. I guess you want to find the sequence of letters in each row and column. What about diagonal? Backwards? Wrapping around?
Two solutions come to mind:
Use a String index:
Build a String of all characters. This needs to be done for each direction (horizontal, vertical, diagonal), but only in the forward order if you reverse the search term for backwards search. For an efficient implementation StringBuilder is your friend.
Use String.indexOf to find occurences of the term in your index. Finally you have to calculate row and column from the String position and, if wrapping is not allowed, check if the word crosses any row/column boundary.
I'd use this if I had to look for many terms.
Use the array
Also for each direction (horizontal, vertical, diagonal)
Look for occurences of the search term's first letter in your array (by simple iteration). Note that you can stop when the term would not fit the row/column, so for a 6-letter word, you can skip the 5 last rows/columns.
If you found an anchor (i.e. matching letter), check the subsequent letters of the word. Cancel on mismatch, otherwise you have found an occurence.
For a more sophisticated matching implementation, the Boyer-Moore algorithm may be of interest.

How do I access and manipulate individual values in a String Array when using a while and for loop

Very new to Java: Trying to learn it.
I created an Array and would like to access individual components of the array.
The first issue I am having is how to I print the array as a batch or the whole array as indicated below? For example: on the last value MyValue4 I added a line break so that when the values are printed, the output will look like this: There has to be a better way to do this?
MyValue1
MyValue2
MyValue3
MyValue4
MyValue1
MyValue2
MyValue3
MyValue4
The next thing I need to do is, manipulate or replace a value with something else, example: MyValue with MyValx, when the repeat variable is at a certain number or value.
So when the repeat variable reaches 3 change my value to something else and then change back when it reaches 6.
I am familiar with the Replace method, I am just not sure how to put this all together.
I am having trouble with changing just parts of the array with the while and for loop in the mix.
My Code:
public static String[] MyArray() {
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
return MyValues;
}
public static void main(String[] args) {
int repeat = 0;
while (repeat < 7) {
for (String lines : MyArray()) {
System.out.println(lines);
}
repeat = repeat + 1;
if (repeat == 7) {
break;
}
}
}
Maybe to use for cycle to be shorter:
for (int i = 0; i < 7; i++) {
for (String lines : MyArray()) {
// Changes depended by values.
if (i > 3) {
lines = MyValx;
}
System.out.println(lines); // to have `\n` effect
}
System.out.println();
}
And BTW variables will start in lower case and not end withenter (\n). So use:
String myValues[] = {"MyValue1", "MyValue2", "MyValue3", "MyValue4"};
instead of:
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
and add System.out.println(); after eache inside cycle instead of this:
MyValues[n] = "value";
where n is the position in the array.
You may consider using System.out.println() without any argument for printing an empty line instead of inserting new-line characters in your data.
You already know the for-each loop, but consider a count-controlled loop, such as
for (int i = 0; i < lines.length; i++) {
...
}
There you can use i for accessing your array as well as for deciding for further actions.
Replacing array items based on a number in a string might be a bit trickier. A regular expression will definitely do the job, if you are familiar with that. If not, I can recommend learning this, because it will sure be useful in future situations.
A simpler approach might be using
int a = Integer.parseInt("123"); // returns 123 as integer
but that only works on strings, which contain pure numbers (positive and negative). It won't work with abc123. This will throw an exception.
These are some ideas, you might try out and experiment with. Also use the documentation excessively. ;-)

How to look for a target in an array using two string array's

So in looking around for an answer to my question, i have only been able to find map structures or just comparing the strings and having to code to stop. I need to be able to essentially translate between languages and print out the translation and have the user to able to ask again to translate another word. I have 2 strings of 10 matching words from English to Russian. I need to able to use a target (or key) to find the translation. Also I need to use a sequential search.
import java.util.*;
public class CISCLabTwo
{
public static void main (String [] args)
{
Scanner keyBoard = new Scanner (System.in);
String [] english = {"House", "Fat", "Monkey", "Trip", "Jumbo", "Chicken", "Unicorn", "Radio", "Shack", "Xylophone"};
String [] russian = {"Dom", "Zhir", "Obeziana", "Poezdka", "Ogromniy", "Kuricha", "Edinorog", "Raadiioo", "Hizhina", "Ksilofon"};
System.out.println ("House, Fat, Monkey, Trip, Jumbo, Chicken, Unicorn, Radio, Shack, Xylophone");
System.out.println("Enter a Word From Above to Translate to Russian: ");
int i = 0;
for (i = 0; i < english.length; i++)
if (english[i]=target){
return i;
}
else{
return - 1;
}
}//end class
public static int translate (String [] english, String target)
}//end main
http://en.wikipedia.org/wiki/Sequential_search
Basically you create a for-loop checking for a match in the english array.
When you have a match the function will return the position of the string in the given array. Use this position to get the corresponding Russian translation.
public static int translate(String [] english, String target)
{
for(int i = 0; i < english.length; i++){
if(english[i].equals(target)){
// Found on position i
return i;
}
}
return -1;
}
You might want to rename the function because it doesn't really translate and only returns an integer and not a string.
Firstly, it's confusing to individually handle two arrays in this way. You probably want to create an extra class in the same file:
class Word {
String english;
String russian;
}
Then you can create the following array:
Word[] words = new Word[10];
That way, you can translate using a separate method, as follows:
String translate(String eng) {
for (Word w : words) if (eng.equals(w.english)) return w.russian;
return null;
}
All you need to do is get the index, print the Russian word then break the loop.
If just printing within main then you can do this.
for (i = 0; i < english.length; i++)
{
if (english[i].equals(target))
{
System.out.println(russian[i]; //Print the russian word
break; //stop looping
}
}
Otherwise if you want to have your translate method that returns the index of the word you could do it like so
public static int translate (String [] english, String target)
{
for (i = 0; i < english.length; i++)
{
if (english[i].equals(target))
return i; // No need for the else statement as it would
// fail on first iteration if it wasnt the word
}
return -1; // After loop exits return -1 as was not found
}
Then in main you would call
String russianWord = russian[translate(english, target)];
As for your code, the proper check is in your for-next loop is
if (english[i].equals(target))
return i;
Also, consider whether the case of the words matters. In your example, is "House" the same as "house"? If case doesn't matter, you should use equalsIgnoreCase() instead of equals, i.e.
if (english[i].equalsIgnoreCase(target))
return i;
(moved later cause it seems like this was homework)
You could save yourself a little work by using two ArrayList to hold the words, since ArrayList has an indexOf() method to do the linear search. (I have no idea why the Arrays utility class does not have an indexOf method).
That said, a map based structure seems like a much better fit (and will be more efficient).

Remove chars from string in Java from file

How would I remove the chars from the data in this file so I could sum up the numbers?
Alice Jones,80,90,100,95,75,85,90,100,90,92
Bob Manfred,98,89,87,89,9,98,7,89,98,78
I want to do this so for every line it will remove all the chars but not ints.
The following code might be useful to you, try running it once,
public static void main(String ar[])
{
String s = "kasdkasd,1,2,3,4,5,6,7,8,9,10";
int sum=0;
String[] spl = s.split(",");
for(int i=0;i<spl.length;i++)
{
try{
int x = Integer.parseInt(spl[i]);
sum = sum + x;
}
catch(NumberFormatException e)
{
System.out.println("error parsing "+spl[i]);
System.out.println("\n the stack of the exception");
e.printStackTrace();
System.out.println("\n");
}
}
System.out.println("The sum of the numbers in the string : "+ sum);
}
even the String of the form "abcd,1,2,3,asdas,12,34,asd" would give you sum of the numbers
You need to split each line into a String array and parse the numbers starting from index 1
String[] arr = line.split(",");
for(int i = 1; i < arr.length; i++) {
int n = Integer.parseInt(arr[i]);
...
try this:
String input = "Name,2,1,3,4,5,10,100";
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
You can make use of the split method of course, supplying "," as the parameter, but that's not all.
The trick is to put each text file's line into an ArrayList. Once you have that, move forwars the Pseudocode:
1) Put each line of the text file inside an ArrayList
2) For each line, Split to an array by using ","
3) If the Array's size is bigger than 1, it means there are numbers to be summed up, else only the name lies on the array and you should continue to the next line
4) So the size is bigger than 1, iterate thru the strings inside this String[] array generated by the Split function, from 1 to < Size (this will exclude the name string itself)
5) use Integer.parseInt( iterated number as String ) and sum it up
There you go
Number Format Exception would occur if the string is not a number but you are putting each line into an ArrayList and excluding the name so there should be no problem :)
Well, if you know that it's a CSV file, in this exact format, you could read the line, execute string.split(',') and then disregard the first returned string in the array of results. See Evgenly's answer.
Edit: here's the complete program:
class Foo {
static String input = "Name,2,1,3,4,5,10,100";
public static void main(String[] args) {
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
System.out.println(result);
}
}
(wow, I never wrote a program before that didn't import anything.)
And here's the output:
125
If you're not interesting in parsing the file, but just want to remove the first field; then split it, disregard the first field, and then rejoin the remaining fields.
String[] fields = line.split(',');
StringBuilder sb = new StringBuilder(fields[1]);
for (int i=2; i < fields.length; ++i)
sb.append(',').append(fields[i]);
line = sb.toString();
You could also use a Pattern (regular expression):
line = line.replaceFirst("[^,]*,", "");
Of course, this assumes that the first field contains no commas. If it does, things get more complicated. I assume the commas are escaped somehow.
There are a couple of CsvReader/Writers that might me helpful to you for handling CSV data. Apart from that:
I'm not sure if you are summing up rows? columns? both? in any case create an array of the target sum counters int[] sums(or just one int sum)
Read one row, then process it either using split(a bit heavy, but clear) or by parsing the line into numbers yourself (likely to generate less garbage and work faster).
Add numbers to counters
Continue until end of file
Loading the whole file before starting to process is a not a good idea as you are doing 2 bad things:
Stuffing the file into memory, if it's a large file you'll run out of memory (very bad)
Iterating over the data 2 times instead of one (probably not the end of the world)
Suppose, format of the string is fixed.
String s = "Alice Jones,80,90,100,95,75,85,90,100,90,92";
At first, I would get rid of characters
Matcher matcher = Pattern.compile("(\\d+,)+\\d+").matcher(s);
int sum = 0;
After getting string of integers, separated by a comma, I would split them into array of Strings, parse it into integer value and sum ints:
if (matcher.find()){
for (String ele: matcher.group(0).split(",")){
sum+= Integer.parseInt(ele);
}
}
System.out.println(sum);

Determining if a given string of words has words greater than 5 letters long

So, I'm in need of help on my homework assignment. Here's the question:
Write a static method, getBigWords, that gets a String parameter and returns an array whose elements are the words in the parameter that contain more than 5 letters. (A word is defined as a contiguous sequence of letters.) So, given a String like "There are 87,000,000 people in Canada", getBigWords would return an array of two elements, "people" and "Canada".
What I have so far:
public static getBigWords(String sentence)
{
String[] a = new String;
String[] split = sentence.split("\\s");
for(int i = 0; i < split.length; i++)
{
if(split[i].length => 5)
{
a.add(split[i]);
}
}
return a;
}
I don't want an answer, just a means to guide me in the right direction. I'm a novice at programming, so it's difficult for me to figure out what exactly I'm doing wrong.
EDIT:
I've now modified my method to:
public static String[] getBigWords(String sentence)
{
ArrayList<String> result = new ArrayList<String>();
String[] split = sentence.split("\\s+");
for(int i = 0; i < split.length; i++)
{
if(split[i].length() > 5)
{
if(split[i].matches("[a-zA-Z]+"))
{
result.add(split[i]);
}
}
}
return result.toArray(new String[0]);
}
It prints out the results I want, but the online software I use to turn in the assignment, still says I'm doing something wrong. More specifically, it states:
Edith de Stance states:
⇒     You might want to use: +=
⇒     You might want to use: ==
⇒     You might want to use: +
not really sure what that means....
The main problem is that you can't have an array that makes itself bigger as you add elements.
You have 2 options:
ArrayList (basically a variable-length array).
Make an array guaranteed to be bigger.
Also, some notes:
The definition of an array needs to look like:
int size = ...; // V- note the square brackets here
String[] a = new String[size];
Arrays don't have an add method, you need to keep track of the index yourself.
You're currently only splitting on spaces, so 87,000,000 will also match. You could validate the string manually to ensure it consists of only letters.
It's >=, not =>.
I believe the function needs to return an array:
public static String[] getBigWords(String sentence)
It actually needs to return something:
return result.toArray(new String[0]);
rather than
return null;
The "You might want to use" suggestions points to that you might have to process the array character by character.
First, try and print out all the elements in your split array. Remember, you do only want you look at words. So, examine if this is the case by printing out each element of the split array inside your for loop. (I'm suspecting you will get a false positive at the moment)
Also, you need to revisit your books on arrays in Java. You can not dynamically add elements to an array. So, you will need a different data structure to be able to use an add() method. An ArrayList of Strings would help you here.
split your string on bases of white space, it will return an array. You can check the length of each word by iterating on that array.
you can split string though this way myString.split("\\s+");
Try this...
public static String[] getBigWords(String sentence)
{
java.util.ArrayList<String> result = new java.util.ArrayList<String>();
String[] split = sentence.split("\\s+");
for(int i = 0; i < split.length; i++)
{
if(split[i].length() > 5)
{
if(split[i].matches("[a-zA-Z]+"))
{
result.add(split[i]);
}
if (split[i].matches("[a-zA-Z]+,"))
{
String temp = "";
for(int j = 0; j < split[i].length(); j++)
{
if((split[i].charAt(j))!=((char)','))
{
temp += split[i].charAt(j);
//System.out.print(split[i].charAt(j) + "|");
}
}
result.add(temp);
}
}
}
return result.toArray(new String[0]);
}
Whet you have done is correct but you can't you add method in array. You should set like a[position]= spilt[i]; if you want to ignore number then check by Float.isNumber() method.
Your logic is valid, but you have some syntax issues. If you are not using an IDE like Eclipse that shows you syntax errors, try commenting out lines to pinpoint which ones are syntactically incorrect. I want to also tell you that once an array is created its length cannot change. Hopefully that sets you off in the right directions.
Apart from syntax errors at String array declaration should be like new String[n]
and add method will not be there in Array hence you should use like
a[i] = split[i];
You need to add another condition along with length condition to check that the given word have all letters this can be done in 2 ways
first way is to use Character.isLetter() method and second way is create regular expression
to check string have only letter. google it for regular expression and use matcher to match like the below
Pattern pattern=Pattern.compile();
Matcher matcher=pattern.matcher();
Final point is use another counter (let say j=0) to store output values and increment this counter as and when you store string in the array.
a[j++] = split[i];
I would use a string tokenizer (string tokenizer class in java)
Iterate through each entry and if the string length is more than 4 (or whatever you need) add to the array you are returning.
You said no code, so... (This is like 5 lines of code)

Categories