Java ArrayList<String> using for loop and overwriting itself - java

I'm trying to make my t String save to an ArrayList. but every time I run my program more than once it overwrites the previous data I want it to be a continuation. Creating the Array inside or out of the loop doesn't seem to help it just keeps rewriting over what is already there.
private void sets(ArrayList<Integer> save, int answer) {
String s = ", ";
String t = "";
for (int i = 0; i < 6; i += 1) {
t = t + String.valueOf(save.get(i)) + s;
}
for(int n = place ;n<1 ;){
ArrayList<String> message = new ArrayList<String>();
message.add(t);
place=place+1;
System.out.println(message);
return;
}
}

Move ArrayList<String> message = new ArrayList<String>(); to right after your class statement. Example:
public class xxxxx{
ArrayList<String> message = new ArrayList<String>();
//rest of your code
}

You can do that in two ways..
You can place the data structure at the beginning of the method sets and this obviously will have all the data in message lost once the method has exited.
private void sets(ArrayList<Integer> save, int answer) {
ArrayList<String> message = new ArrayList<String>();
String s = ", ";
String t = "";
for (int i = 0; i < 6; i += 1) {
t = t + String.valueOf(save.get(i)) + s;
}
for (int n = place; n < 1;) {
message.add(t);
place = place + 1;
System.out.println(message);
}
return;
}
Or you can declare a global variable that can always handle your data for as long as the program still executes.
private ArrayList<String> message = new ArrayList<String>();
private void sets(ArrayList<Integer> save, int answer) {
String s = ", ";
String t = "";
for (int i = 0; i < 6; i += 1) {
t = t + String.valueOf(save.get(i)) + s;
}
for (int n = place; n < 1;) {
message.add(t);
place = place + 1;
System.out.println(message);
}
return;
}
It all comes down to your requirements. #GOODLUCK

Related

Why is Java string array appending a string to null in first cell?

Here is my class below, that compares elements in two string arrays, and returns the word with the highest frequency in both arrays. However as visible from the output, the first index is appending none to null in spite of initializing both arrays with the String none. Can someone kindly let me know what I am doing wrong that is leading to this?
public class HelloWorld{
public String[] pro;
public String[] con;
String proSplitter;
String conSplitter;
public HelloWorld() {
this.pro = new String[9];
this.con = new String[9];
for(int i=0;i<this.pro.length;i++)
{
this.pro[i]="none";
this.con[i]="none";
}
}
public String[] getPro() {
return pro;
}
public String[] getCon() {
return con;
}
public void setPro(String pros, int proIndex) {
pro[proIndex] = pros;
}
public void setCon(String cons, int conIndex) {
con[conIndex] = cons;
}
public String[] proWord(){
for(int i=0;i<9;i++)
{
proSplitter = proSplitter + pro[i] + ",";
}
for(int i=0;i<9;i++)
{
conSplitter = conSplitter + con[i] + ",";
}
String[] values = proSplitter.split(",");
for(int i=0;i<values.length;i++)
{
values[i] = values[i].trim();
}
String[] values1 = conSplitter.split(",");
for(int i=0;i<values1.length;i++)
{
values1[i] = values1[i].trim();
}
int [] fr = new int [values.length];
int visited = -1;
for(int i = 0; i < values.length; i++){
int count = 1;
for(int j = i+1; j < values.length; j++){
if(!values[i].equalsIgnoreCase("none"))
{
if(values[i].compareTo(values[j])==0){
count++;
//To avoid counting same element again
fr[j] = visited;
}
}
}
if(fr[i] != visited)
fr[i] = count;
}
int max = fr[0];
int index = 0;
for (int i = 0; i < fr.length; i++)
{
if (max < fr[i])
{
max = fr[i];
index = i;
}
}
int [] fr1 = new int [values1.length];
int visited1 = -1;
for(int i = 0; i < values1.length; i++){
int count1 = 1;
for(int j = i+1; j < values1.length; j++){
if(!values1[i].equalsIgnoreCase("none"))
{
if(values1[i].compareTo(values1[j])==0){
count1++;
//To avoid counting same element again
fr1[j] = visited1;
}
}
}
if(fr1[i] != visited1)
fr1[i] = count1;
}
for(int i = 0;i<values.length;i++)
{
System.out.println("pro = "+values[i]);
}
for(int i = 0;i<values1.length;i++)
{
System.out.println("con = "+values1[i]);
}
int max1 = fr1[0];
int index1 = 0;
for (int i = 0; i < fr1.length; i++)
{
if (max1 < fr1[i])
{
max1 = fr1[i];
index1 = i;
}
}
String sentence[] = new String[2];
if(values[index].equalsIgnoreCase(values1[index1])) {
sentence[0] = "balanced";
}else {
sentence[0] = values[index];
sentence[1] = values1[index1];
}
return sentence;
}
public static void main(String[] args){
HelloWorld tracker = new HelloWorld();
tracker.setPro("Apple, Pear", 1);
tracker.setCon("Banana", 1);
tracker.setPro("Apple", 2);
tracker.setCon("Water Melon", 2);
tracker.setPro("Guava", 3);
tracker.setCon("Ball", 3);
tracker.setPro("Apple", 4);
tracker.setCon("Mango, Plum", 4);
String[] arr = tracker.proWord();
System.out.println("pro = "+arr[0]);
System.out.println("con = "+arr[1]);
}
}
The output being generated is :
pro = nullnone
pro = Apple
pro = Pear
pro = Apple
pro = Guava
pro = Apple
pro = none
pro = none
pro = none
pro = none
con = nullnone
con = Banana
con = Water Melon
con = Ball
con = Mango
con = Plum
con = none
con = none
con = none
con = none
pro = Apple
con = nullnone
As mentioned by Arnaud, the immediate problem is that you're leaving proSplitter uninitialized, so its value is null. Then, when you come to append a string to it with proSplitter = proSplitter + pro[i] + ",";, proSplitter will be converted (effectively) to "null", and then stuff is appended to the end. So, instead, make it "" initially.
However, you've got another problem here, which is that you're mutating a member variable each time you invoke that method - so it's not null (or empty) second time around, it still contains what was there previously.
The fix for that is straightforward: instead of using a member variable, declare these as local variables.
You've also got the problem that you're effectively duplicating the code to count the most frequent thing in an array: this is what methods are for, to allow you to run the same code over different inputs.
You can also make use of library methods. For example:
String mostFrequent(String[] array) {
int maxFreq = 0;
String maxFreqS = "";
for (String s : array) {
if (s.equalsIgnoreCase("none")) continue;
int freq = Collections.frequency(Arrays.asList(array), s);
if (freq > maxFreq) {
maxFreq = freq;
maxFreqS = s;
}
}
return maxFreqS;
}
(There are lots of inefficiencies here. The point is more about writing this as a method, to remove the duplication).
Then you can use this inside your existing method, and it will be a whole lot easier for others - and you - to read.

Getting names from text file shifts names 1 place to the left (in array)

I was trying to solve problem 22 of Euler Project. Description of what I'm trying to solve is here:
https://projecteuler.net/problem=22
Where's the problem?: I've got the names from the text file, put them on one string,
edited the string so that the names are separated by one space.
After getting those names on an array of Strings, I sort them. After finishing the program and getting the result wrong, I started testing different parts of the program and notice that the name "COLIN", which by eulerproject page is said to be the 938th, is 937th on my array. I can't seem to get why is it happening and how to fix this. Help would be much appreciated.
Here is the code:
package Project022;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class NameScore {
private long scoreSum;
private LinkedList<String> allNames;
private String[] sortedNames;
private int[] nameScores;
public NameScore(){
scoreSum = 0;
allNames = new LinkedList<>();
getNames();
}
private void getNames(){
List<String> content = null;
File names;
// read "names.txt" file and put all the names in one line(not effective when line
// length surpasses String maximum character range(2^31 - 1) but is good enough for us
// for now)
try {
names = new File("Project022\\names.txt");
content = Files.readAllLines(Paths.get(names.getPath()), StandardCharsets.US_ASCII);
} catch (Exception e){
System.out.println("something went wrong while getting the file");
}
assert content != null;
//replace (",") with a space ( )
String filtered = content.get(0).replaceAll("\",\"", " ");
//then remove first and last (")
filtered = filtered.substring(1, filtered.length() - 1);
//declare "tempName" as a helper string
StringBuilder tempName = new StringBuilder();
//get every name and put it on the LinkedList
for (int i = 0; i < filtered.length(); i++) {
if (filtered.charAt(i) != ' '){
tempName.append(filtered.charAt(i));
} else {
allNames.add(tempName.toString().trim());
tempName = new StringBuilder();
}
}
//now we use an pre defined array since it is faster.
sortedNames = new String[allNames.size()];
for (int i = 0; i < sortedNames.length; i++) {
sortedNames[i] = allNames.get(i);
}
//make the new array worthy of its name
Arrays.sort(sortedNames);
System.out.println(sortedNames[937]);
System.out.println(Arrays.asList(sortedNames) + "\n" + sortedNames.length);
}
public void calculate(){
//we set the score for each name
nameScores = new int[sortedNames.length];
//
for (int i = 0; i < nameScores.length; i++) {
setScore(sortedNames[i], i + 1);
}
for (int i = 0; i < nameScores.length; i++) {
scoreSum += nameScores[i];
}
}
private void setScore(String name, int n) {
int sc = 0;
for (int i = 0; i < name.length(); i++) {
sc += (int)name.toUpperCase().charAt(i) - 'A' + 1;
}
sc *= n;
nameScores[n-1] = sc;
}
#Override
public String toString(){ return "the score of all names is: " + scoreSum; }
public static void main(String[] args) {
NameScore name = new NameScore();
name.calculate();
System.out.println(name);
}
}
What I've ruled out as a problem:
the setScore() method which gives a score for every name, because I tested it with examples by hand and by program and got same results.
the calculate() method, since what it does is gets the score for each name and adds to the total sum.
This works for me.
Path p = Paths.get("p022_names.txt");
try {
List<String> lines = Files.readAllLines(p); // throws java.io.IOException
System.out.println(lines.size()); // Only one line in file.
// Remove all " (double quotes) characters.
String tmp = lines.get(0).replaceAll("\"", "");
String[] names = tmp.split(",");
System.out.println(names.length);
Arrays.sort(names);
// Test against example given in problem description.
System.out.println(names[937]); // Should be COLIN
char[] lett = names[937].toCharArray();
int sigma = 0;
for (int k = 0; k < lett.length; k++) {
sigma += lett[k] - 'A' + 1; // Since only uppercase letters in file.
}
int score = sigma * (937 + 1);
System.out.println(score); // Should be 49714
// Now obtain answer, i.e. the total of all the name scores in the file.
int total = 0;
for (int i = 0; i < names.length; i++) {
char[] letters = names[i].toCharArray();
int sum = 0;
for (int j = 0; j < letters.length; j++) {
sum += letters[j] - 'A' + 1;
}
total += sum * (i + 1);
}
System.out.println(total);
}
catch (IOException xIo) {
xIo.printStackTrace();
}
Output obtained when running above code is as follows.
1
5163
COLIN
49714
871198282
I didn't want to make too many changes to your code, so just removed your replacement of "," and instead just removed all ". Then I added ALONSO in the end after the loop.
I figure if we're all in consensus about the total score of all the names, then we're doing it right :)
It prints:
-- Where's ALONSO ?
sortedNames[145] = ALONA
sortedNames[146] = ALONSO
sortedNames[147] = ALONZO
-- Where's COLIN ?
sortedNames[936] = COLETTE
sortedNames[937] = COLIN
sortedNames[938] = COLLEEN
-- Where's MARY ?
sortedNames[3361] = MARX
sortedNames[3362] = MARY
sortedNames[3363] = MARYA
-- sortedNames.length = 5163
the score of all names is: 871198282
I also called it Project022:
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
//public class NameScore {
public class Project022 {
private long scoreSum;
private LinkedList<String> allNames;
private String[] sortedNames;
private int[] nameScores;
public Project022(){
scoreSum = 0;
allNames = new LinkedList<>();
getNames();
}
private void getNames(){
List<String> content = null;
File names;
// read "names.txt" file and put all the names in one line(not effective when line
// length surpasses String maximum character range(2^31 - 1) but is good enough for us
// for now)
try {
// names = new File("Project022\\names.txt");
names = new File("resource\\p022_names.txt");
content = Files.readAllLines(Paths.get(names.getPath()), StandardCharsets.US_ASCII);
} catch (Exception e){
System.out.println("something went wrong while getting the file");
}
assert content != null;
//replace (",") with a space ( )
// String filtered = content.get(0).replaceAll("\",\"", " ");
String filtered = content.get(0).replaceAll("\"", "");
// //then remove first and last (")
// filtered = filtered.substring(1, filtered.length() - 1);
//declare "tempName" as a helper string
StringBuilder tempName = new StringBuilder();
//get every name and put it on the LinkedList
for (int i = 0; i < filtered.length(); i++) {
// if (filtered.charAt(i) != ' '){
if (filtered.charAt(i) != ','){
tempName.append(filtered.charAt(i));
} else {
allNames.add(tempName.toString().trim());
tempName = new StringBuilder();
}
}
allNames.add(tempName.toString().trim()); // added to include ALONSO
//now we use an pre defined array since it is faster.
sortedNames = new String[allNames.size()];
for (int i = 0; i < sortedNames.length; i++) {
sortedNames[i] = allNames.get(i);
}
//make the new array worthy of its name
Arrays.sort(sortedNames);
System.out.println("\n -- Where's ALONSO ?");
for (int i = 145; i < 148; i++) {
// sortedNames[0] = AARON
System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
}
System.out.println("\n -- Where's COLIN ?");
for (int i = 936; i < 939; i++) {
// sortedNames[0] = AARON
System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
}
System.out.println("\n -- Where's MARY ?");
for (int i = 3361; i < 3364; i++) {
// sortedNames[0] = AARON
System.out.println("sortedNames[" + i + "] = " + sortedNames[i]);
}
System.out.println("\n -- sortedNames.length = " + sortedNames.length + "\n");
// System.out.println(Arrays.asList(sortedNames) + "\n" + sortedNames.length);
}
public void calculate(){
//we set the score for each name
nameScores = new int[sortedNames.length];
//
for (int i = 0; i < nameScores.length; i++) {
setScore(sortedNames[i], i + 1);
}
for (int i = 0; i < nameScores.length; i++) {
scoreSum += nameScores[i];
}
}
private void setScore(String name, int n) {
int sc = 0;
for (int i = 0; i < name.length(); i++) {
sc += (int)name.toUpperCase().charAt(i) - 'A' + 1;
}
sc *= n;
nameScores[n-1] = sc;
}
#Override
public String toString(){ return "the score of all names is: " + scoreSum; }
public static void main(String[] args) {
Project022 name = new Project022();
name.calculate();
System.out.println(name);
}
}

Arrays are null. Not getting information from while loop

The following snippet of code is supposed to read from a text file, check how many words are in the file, and how many lines there are, and with that information it's supports to sort the nth word into it's appropriate array.
protected static void loadAccountInformationFromFile() throws Exception
{
// These variables control the logic needed to put words in the right array
int accountNumberCount = 1;
int firstNameCount = 2;
int lastNameCount = 3;
int balanceCount = 4;
int lastVariableCount = 5;
int sortCount = 1;
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
// Using word count to get the nth value later
int wordCount = 0;
while(account.hasNext())
{
account.next();
wordCount++;
}
// If the count is zero it means the account list is empty
if (wordCount == 0)
{
System.err.println("error: Account list empty.");
System.exit(1);
}
// Used to test word count feature:
// System.out.println("Number of words: " + wordCount);
int lineCount = wordCount / MAX_VALUES_PER_LINE;
// These arrays will be used to put the account information in the correct place
// Using the lineCount to create the Array of however large it needs to be
String[] accountNumber = new String[lineCount - 1];
String[] firstName = new String[lineCount - 1];
String[] lastName = new String[lineCount - 1];
String[] balance = new String[lineCount - 1];
String[] lastVariable = new String[lineCount - 1];
// If I don't close and open a new Scanner I get a compiler error
account.close();
Scanner account2 = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
do
{
String[] temp1 = account2.next().split(",");
String temp2 = "" + temp1;
if (sortCount == accountNumberCount)
{
accountNumber[sortCount] = temp2;
}
if (sortCount == firstNameCount)
{
firstName[sortCount] = temp2;
}
if (sortCount == lastNameCount)
{
lastName[sortCount] = temp2;
}
if (sortCount == balanceCount)
{
balance[sortCount] = temp2;
}
if (sortCount == lastVariableCount)
{
lastVariable[sortCount] = temp2;
}
accountNumberCount += 5;
firstNameCount += 5;
lastNameCount += 5;
balanceCount += 5;
lastVariableCount += 5;
sortCount++;
{
}
}
while (account2.hasNext());
// testing to see if it works, but it only returns:
// [null, [Ljava.lang.String;#55f96302, null, null, null]
System.out.println(Arrays.toString(accountNumber));
// This one only returns [Ljava.lang.String;#55f96302
System.out.println(accountNumber[1]);
account2.close();
}
It has no problem opening the file and counting the words properly. However, when it came time to put the words into the appropriate array it doesn't work, as indicated in the commenting out text.
My question is: Why? And how can I get this to work properly without using BufferedWriter / BufferedReader?
Based on an answer, I corrected a flaw in the logic only to end up with
run:
error: 6
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Here's the modified code:
public class Main
{
private final static int ACCOUNT_NUMBER_INDEX = 0;
private final static int FIRST_INDEX = 1;
private final static int LAST_INDEX = 2;
private final static int BALANCE_INDEX = 3;
private final static int FREE_CHECKS_INDEX = 4;
private final static int INTEREST_INDEX = 4;
private final static int MAX_VALUES_PER_LINE = 5;
private final static String INPUT_ACCOUNT_FILE = "accountInfo.txt";
protected static String[] fields;
protected static void loadAccountInformationFromFile() throws Exception
{
// These variables control the logic needed to put words in the right array
int accountNumberCount = 0;
int firstNameCount = 1;
int lastNameCount = 2;
int balanceCount = 3;
int lastVariableCount = 4;
int sortCount = 1;
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
// Using word count to get the nth value later
int wordCount = 0;
while(account.hasNext())
{
account.next();
wordCount++;
}
// If the count is zero it means the account list is empty
if (wordCount == 0)
{
System.err.println("error: Account list empty.");
System.exit(1);
}
// Used to test word count feature:
// System.out.println("Number of words: " + wordCount);
int lineCount = wordCount / MAX_VALUES_PER_LINE;
// These arrays will be used to put the account information in the correct place
// Using the lineCount to create the Array of however large it needs to be
String[] accountNumber = new String[lineCount];
String[] firstName = new String[lineCount];
String[] lastName = new String[lineCount];
String[] balance = new String[lineCount];
String[] lastVariable = new String[lineCount];
// If I don't close and open a new Scanner I get a compiler error
account.close();
Scanner account2 = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
do
{
String[] temp1 = account2.next().split(",");
String temp2 = "" + temp1;
if (sortCount == accountNumberCount)
{
accountNumber[sortCount] = temp2;
accountNumberCount += MAX_VALUES_PER_LINE;
}
if (sortCount == firstNameCount)
{
firstName[sortCount] = temp2;
firstNameCount += MAX_VALUES_PER_LINE;
}
if (sortCount == lastNameCount)
{
lastName[sortCount] = temp2;
lastNameCount += MAX_VALUES_PER_LINE;
}
if (sortCount == balanceCount)
{
balance[sortCount] = temp2;
balanceCount += MAX_VALUES_PER_LINE;
}
if (sortCount == lastVariableCount)
{
lastVariable[sortCount] = temp2;
lastVariableCount += MAX_VALUES_PER_LINE;
}
sortCount++;
}
while (account2.hasNext());
// testing to see if it works, but it only returns:
// [null, [Ljava.lang.String;#55f96302, null, null, null]
System.out.println(Arrays.toString(accountNumber));
// This one only returns [Ljava.lang.String;#55f96302
System.out.println(accountNumber[1]);
account2.close();
This happens because on every iteration of the loop, you increase all the count variables.
When coming to the loop for the first time you have the following variables:
accountNumberCount == 1
firstNameCount == 2
lastNameCount == 3
balanceCount == 4
lastVariableCount == 5
sortCount == 1
So sortCount == accountNumberCount and that means you put the word into accountNumber array to the second position (index starts from 0 on arrays).
Then you increase all the above variables and go for round two, having the following situation:
accountNumberCount == 6
firstNameCount == 7
lastNameCount == 8
balanceCount == 9
lastVariableCount == 10
sortCount == 2
Thus on second iteration sortCount no longer equals any of the other variables. Same thing happens on further iterations and you end up with only one word inserted into one of the five arrays.
If you want to make this work, I'd suggest using ArrayLists (so you don't have to worry about array indexes or array sizes) instead of arrays and to only change one variable per each iteration.
private static final int ACCOUNT_NUMBER_COUNT = 1;
private static final int FIRST_NAME_COUNT = 2;
private static final int LAST_NAME_COUNT = 3;
private static final int BALANCE_COUNT = 4;
private static final int LAST_VARIABLE_COUNT = 5;
List<String> accountNumbers = new ArrayList<String>();
List<String> firstNames = new ArrayList<String>();
List<String> lastNames = new ArrayList<String>();
List<String> balances = new ArrayList<String>();
List<String> lastVariables = new ArrayList<String>();
int sortCount = 1;
// Other things...
do {
if (sortCount == ACCOUNT_NUMBER_COUNT) {
accountNumbers.add(temp2);
} else if (sortCount == FIRST_NAME_COUNT) {
firstNames.add(temp2);
} else if (sortCount == LAST_NAME_COUNT) {
lastNames.add(temp2);
} else if (sortCount == BALANCE_COUNT) {
balances.add(temp2);
} else if (sortCount == LAST_VARIABLE_COUNT) {
lastVariables.add(temp2);
}
if (sortCount < 5) {
sortCount++;
} else {
sortCount = 1;
}
} while (account2.hasNext());
Personally I'd read line by line using BufferedReader, that way you do not need to calculate the number of lines,
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
}

could some help me find why my code couldn't run [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Java code with tests - infinite loop?
Here is my code that I want to get the relationship between people, however, when I run unit test, the test ran forever and couldn't get the result, and my cpu using was high.
Here is my code. Could someone see what's wrong with it?
the string relations are multiple line inputs of string with a format "A , B" +\n" +
"C , D" where A is the parent of B and C is the parent of D.
this is the default constructor for the code and is the input format of string, we don't need to check if the format is correct
public SeeRelations(String relations){
this.relations = relations;
}
//helper function to get each line of the string
private ArrayList<String> lineRelations(){
int i;
ArrayList<String> lineRelations = new ArrayList<String>();
String[] lines = relations.split("\n");
for(i = 0; i < lines.length; i++){
lineRelations.add(lines[i]);
}
return lineRelations;
}
//helper function to put each of the relationship in arraylists
private ArrayList<ArrayList<String>> allRelations(){
int i;
ArrayList<ArrayList<String>> allRelations = new ArrayList<ArrayList<String>>();
ArrayList<String> lineRelations = lineRelations();
for(i = 0; i < lineRelations.size(); i++){
ArrayList<String> eachLine = new ArrayList<String>(Arrays.asList(lineRelations.get(i).split("\\s*,\\s*")));
allRelations.add(eachLine);
}
return allRelations;
}
this is the method to check if the input name is existent
//helper function to see if the name exist for seeRelations()
private boolean hasThisName(String name){
ArrayList<ArrayList<String>> allRelations = allRelations();
int i;
int j;
for(i = 0; i < allRelations.size(); i++){
for(j = 0; j < allRelations.get(i).size(); j++){
if(name.equals(allRelations.get(i).get(j))){
return true;
}
}
}
return false;
}
this is the function to get the generation number between two people
//helper function to get Generation number of seeRelations()
private int getGenerationNum(String person, String ancestor){
ArrayList<ArrayList<String>> allRelations = allRelations();
String name;
int i;
int j;
int generationNum = 0;
for(i = 0, j = 0, name = ancestor; i < allRelations.size(); i++){
if(name.equals(allRelations.get(i).get(0)) && !person.equals(allRelations.get(i).get(1))){
generationNum++;
ancestor = allRelations.get(i).get(1);
i = 0;
j = 1;
}
else if(ancestor.equals(allRelations.get(i).get(0)) && person.equals(allRelations.get(i).get(1))){
generationNum++;
j = 1;
break;
}
}
if(j == 0){
return 0;
}
else{
return generationNum;
}
}
this is the method to get multiple of "great" for the final output
private String great(int num){
int i;
String great = "";
for(i = 0; i < num; i++){
great += "great";
}
return great;
}
this is my final method to check the relationship between two people
public String seeRelations(String person, String ancestor){
int generationNum = getGenerationNum(person, ancestor);
String great = great(generationNum - 2);
if(!(hasThisName(person) && hasThisName(ancestor))){
return null;
}
else{
if(generationNum == 0){
return null;
}
else if(generationNum == 1){
return ancestor + " is the parent of " + person;
}
else if(generationNum == 2){
return ancestor + " is the grandparent of " + person;
}
else{
return ancestor + " is the" + " " + great +"grandparent of " + person;
}
}
}
This piece of code looks suspicious to me. It is inside a loop that depends for termination on incrementing i, but conditionally resets i back to zero. What guarantees i will ever get past 1?
if(name.equals(allRelations.get(i).get(0)) && !person.equals(allRelations.get(i).get(1))){
generationNum++;
ancestor = allRelations.get(i).get(1);
i = 0;
j = 1;
}
In general, I suggest simplifying your code until it works, then adding gradually so that you only have to debug a small piece of code at a time.

Add to list at certain index

I'm having a problem with some list manipulation. I take the user's input and search through it: if i find an "=" sign i assume that the string in front of it is the name of a variable , so on the line right above that variable i want to add a new string to the user's input (in this case it is called "tempVAR", doesn't really matter though). I've been trying to do this with StringBuilder but without any success , so i currently am trying to do it with ArrayLists but I am getting stuck at adding new elements to the list. Because of the way list.add(index,string) works , the elements to the right of what i am adding will always add +1 to their index. Is there a way to always know exactly what index i am looking for even after a random number of string has been added? Here is my code so far, if you run it you will see what i mean, instead of "tempVAR" or "tempVar1" being added above the name of the variable they will be added one or to positions in the wrong way.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
public class ToTestStuff {
static List<String> referenceList = new ArrayList<String>();
public static final String SEMICOLUMN = ";";
public static final String BLANK = " ";
public static final String EMPTY = "";
public static final String LEFT_CURLY = "{";
public static final char CARRIAGE_RETURN = '\r';
public static final String CR_STRING = "CARRIAGE_RETURN_AND_NEW_LINE";
public static final char NEW_LINE = '\n';
public static void main(String[] args) {
List<String> test = new ArrayList<String>();
String x = "AGE_X";
String y = "AGE_Y";
String z = "AGE_YEARS";
String t = "P_PERIOD";
String w = "T_VALID";
referenceList.add(x);
referenceList.add(y);
referenceList.add(z);
referenceList.add(t);
referenceList.add(w);
String text2 = " if ( AGE_YEARS > 35 ) {\r\n"
+ " varX = P_PERIOD ;\r\n"
+ " }\r\n"
+ " if ( AGE_YEARS < 35 ) {\r\n"
+ " varY = T_VALID ;\r\n"
+ " varZ = AGE_Y ;\r\n"
+ " varA = AGE_X ;\r\n"
+ " }";
detectEquals(text2);
}
public static String detectEquals(String text) {
String a = null;
// text = text.trim();
// text = TestSplitting.addDelimiters(text);
String[] newString = text.split(" ");
List<String> test = Arrays.asList(newString);
StringBuilder strBuilder = new StringBuilder();
HashMap<String, List<Integer>> signs = new HashMap<String, List<Integer>>();
HashMap<String, List<Integer>> references = new HashMap<String, List<Integer>>();
HashMap<Integer, Integer> indexesOfStringAndList = new HashMap<Integer, Integer>();
List<String> testList = new ArrayList<String>();
List<Integer> lastList = new ArrayList<Integer>();
List<Integer> indexList = new ArrayList<Integer>();
List<Integer> refList = new ArrayList<Integer>();
List<String> keysList = new ArrayList<String>();
List<List> minList = new ArrayList<List>();
String previous = null;
int index = 0;
Object obj = new Object();
List<Integer> referenceValueList = new ArrayList<Integer>();
List<Integer> indexPosition = new ArrayList<Integer>();
String b = null;
int indexOfa = 0;
// System.out.println("a----> " + test);
List<String> anotherList = new ArrayList(test);
for (int i = 0; i < anotherList.size(); i++) {
a = anotherList.get(i).trim();
index = strBuilder.length();// - a.length();
// index = i;
strBuilder.append(a); // "=", 3 - if, 14 - while, 36 , "=", 15
testList.add(a);
if (a.equals("if") || a.equals("=")) {
lastList.add(i);
indexOfa = i;
indexesOfStringAndList.put(index, indexOfa);
refList.add(index);
indexPosition.add(index);
if (signs.containsKey(a)) {
signs.get(a).add(index);
} else {
signs.put(a, refList);
}
refList = new ArrayList<Integer>();
}
if (referenceList.contains(a)) {
indexList.add(index);
if (references.containsKey(a)) {
references.get(a).add(index);
} else {
references.put(a, indexList);
}
indexList = new ArrayList<Integer>();
}
}
for (String k : references.keySet()) {
keysList.add(k);
referenceValueList = references.get(k);
obj = Collections.min(referenceValueList);
int is = (Integer) obj;
ArrayList xx = new ArrayList();
xx.add(new Integer(is));
xx.add(k);
minList.add(xx);
}
for (List q : minList) {
Integer v = (Integer) q.get(0);
String ref = (String) q.get(1);
int x = closest(v, indexPosition);
int lSize = anotherList.size();
int sizeVar = lSize - test.size();
int indexOfPx = 0;
int px = 0;
if (x != 0) {
px = indexesOfStringAndList.get(x) - 1;
} else {
px = indexesOfStringAndList.get(x);
}
if (px == 0) {
System.out.println("previous when x=0 " +anotherList.get(px+sizeVar));
anotherList.add(px, "tempVar1=\r\n");
} else {
previous = anotherList.get(px + sizeVar);
System.out.println("previous is---> " + previous + " at position " + anotherList.indexOf(previous));
anotherList.add(anotherList.indexOf(previous) - 1, "\r\ntempVAR=");
}
}
strBuilder.setLength(0);
for (int j = 0; j < anotherList.size(); j++) {
b = anotherList.get(j);
strBuilder.append(b);
}
String stream = strBuilder.toString();
// stream = stream.replaceAll(CR_STRING, CARRIAGE_RETURN + EMPTY + NEW_LINE);
System.out.println("after ----> " + stream);
return stream;
}
public static int closest(int of, List<Integer> in) {
int min = Integer.MAX_VALUE;
int closest = of;
for (int v : in) {
final int diff = Math.abs(v - of);
if (diff < min) {
min = diff;
closest = v;
}
}
return closest;
}
}
I've mapped the positions of the "=" and "if" to their positions in the StringBuilder, but these are remnants from when i was trying to use a stringBuilder to do what i said above.
I have been struggling with this for a few days now and still haven't managed to do what i need, i am not sure where i am going wrong. At the moment i am hellbent on making this work as it is (with either lists or string builder) after which , if there is a better way i will look into that and adapt this accordingly.
The addDelimiters() method is a method i created to avoid writing the string as you see it in "String text2" but i took that out for this because it would only clutter my already chaotic code even more :), i don't think it has any relevance to why what i am trying to do is not working.
TLDR: at the line above front of every varX or varY or other "var" i would like to be able to add a string to the list but i think my logic in getting the variable names or in adding to the list is wrong.
I think we both know that your code is messed up and that you need many more abstractions to make it better. But you could make it work by maintaining an offset variable, lets say "int offset". Each time you insert a string after the initial pass you increment it, and when you access the list you use it, "list.get(index+offset);". Read up on Abstract syntax trees. , which are a great way to parse and manipulate languages.

Categories