Program Overwriting Array with Null - java

For a project in school (intro to java), we have to make a program using arrays. I decided to make a login program that stores logins. It works perfectly, except when deleting items. This is my code
public void delete() throws FileNotFoundException{
int p;
c.clear();
c.print("Please enter a website to delete it's login info: ");
String delete_name = c.readLine();
Boolean found = false;
// Search for the search key, and display the matching elements
c.println("Searching for " + delete_name + "...");
for (int i = 0; i < pass.length; i++)
if (pass[i][0].equals(delete_name)) {
c.println("Deleting login for " + pass[i][0]);
String new_array[][] = new String[pass.length - 1][3];
//remove an element
for (int w = 0; i < new_array.length; i++)
for (int j = 0; j <= 2; j++) {
p = w;
if (i >= p) {
new_array[w][j] = pass[w + 1][j];
} else {
new_array[w][j] = pass[w][j];
}
}
found = true;
pass = new_array;
}
if (found == false) {
c.println("No luck! " + delete_name + " wasn't found, please try again.");
delete();
}
fileWriter();
}
When it writes to the file, anything after the part that should have been deleted gets changed to "null".
Sorry if the format is awful, I'm just starting with java :) Any help is greatly appreciated, thanks!

When deleting a row of a 2D array in Java, you can use this shortcut (no for-loops needed)
List<String[]> tempArr = new ArrayList<String[]>(Arrays.asList(pass));
//Remove row at index of "delete_name":
for(int i = 0; i < pass.length; i++){
if(pass[i][0].equals(delete_name)){
tempArr.remove(i);
}
}
String[][] new_array = tempArr.toArray(new String[][]{});
However, this solution only works if you are only deleting one object in the List. I would suggest looking into "iterators" to make this solution better.
EDIT:
Here is an example with an iterator
String[][] pass = new String[][]{{"Name","data1","data2"}};
List<String[]> tempArr = new ArrayList<String[]>(Arrays.asList(pass));
for (Iterator<String[]> iterator = tempArr.iterator(); iterator.hasNext();) {
String id = iterator.next()[0];
if (id.equals(delete_name)){
iterator.remove();
}
}

Related

chatBot conversations challenge, is my code inefficient? Failing hidden test cases

Edit: This is a code challenge. I actually just ran it again and it was more specific that the code is innificient. See here and here.
I can't figure out what exactly is wrong with my code. It passes all the visible test cases but fails 4/5 the hidden test cases.
The challenge is to try to predict the next words of a given conversation (currentConversation) using a history of previous conversations (conversations). If a historical conversation has words matching the currentConversation, append the rest of the historical conversation to the currentConversation.
This is my code in Java:
public String[] chatBot(String[][] conversations, String[] currentConversation) {
int hmNumOfMatches = 0; // highest matched conversation's similar words to the current conversation
ArrayList<String> hmRestOfWords = new ArrayList<>(); // the rest of the words in the matched conversation
// for all given conversations
for (String[] pc : conversations) {
int numOfMatches = 0;
int indexOfLastMatchingWord = -1;
HashSet<String> uw = new HashSet<String>(); // stores the unique words in pc (possible conversation)
// for all words of possible conversation
for (int j = 0; j < pc.length; j++) {
String pw = pc[j]; // possible word
// exclude words that have already been accounted for
if (!uw.contains(pw)) {
// for all words in the current conversation
for (int i = 0; i < currentConversation.length; i++) {
String w = currentConversation[i];
if (w.compareTo(pw) == 0) {
numOfMatches++;
indexOfLastMatchingWord = j;
}
}
uw.add(pw);
}
}
ArrayList<String> restOfWords = new ArrayList<>();
// if there were matching words
if (indexOfLastMatchingWord != -1)
restOfWords = getRestOfWords(pc, indexOfLastMatchingWord);
else continue;
// set the highest number of matches if it has none
if (hmNumOfMatches == 0) {
hmNumOfMatches = numOfMatches;
hmRestOfWords.addAll(restOfWords);
}
// also update it if it's less then the current number of matches
if (hmNumOfMatches < numOfMatches) {
hmNumOfMatches = numOfMatches;
hmRestOfWords = restOfWords;
}
}
/**
* Create the answer
*/
String[] answer = new String[currentConversation.length + hmRestOfWords.size()];
int i;
// append the current conversation to the answer
for (i = 0; i < currentConversation.length; i++) {
answer[i] = currentConversation[i];
}
// and append the rest of the words from the matched historical conversation
for (int j = 0; j < hmRestOfWords.size(); j++) {
answer[i + j] = hmRestOfWords.get(j);
}
return answer;
}
public ArrayList<String> getRestOfWords(String[] pc, int indexOfLastMatchingWord) {
ArrayList<String> restOfWords = new ArrayList<String>();
for (int i = indexOfLastMatchingWord + 1; i < pc.length; i++) {
if (!restOfWords.contains(pc[i])) restOfWords.add(pc[i]);
}
return restOfWords;
}

sub arraylist's size isn't correct

After hard searchig I still haven't found the proper answer for my question and there is it:
I have to write a java program that enters an array of strings and finds in it the largest sequence of equal elements. If several sequences have the same longest length, the program should print the leftmost of them. The input strings are given as a single line, separated by a space.
For example:
if the input is: "hi yes yes yes bye",
the output should be: "yes yes yes".
And there is my source code:
public static void main(String[] args) {
System.out.println("Please enter a sequence of strings separated by spaces:");
Scanner inputStringScanner = new Scanner(System.in);
String[] strings = inputStringScanner.nextLine().split(" ");
System.out.println(String.join(" ", strings));
ArrayList<ArrayList<String>> stringsSequencesCollection = new ArrayList<ArrayList<String>>();
ArrayList<String> stringsSequences = new ArrayList<String>();
stringsSequences.add(strings[0]);
for (int i = 1; i < strings.length; i++) {
if(strings[i].equals(strings[i - 1])) {
stringsSequences.add(strings[i]);
} else {
System.out.println(stringsSequences + " " + stringsSequences.size());
stringsSequencesCollection.add(stringsSequences);
stringsSequences.clear();
stringsSequences.add(strings[i]);
//ystem.out.println("\n" + stringsSequences);
}
if(i == strings.length - 1) {
stringsSequencesCollection.add(stringsSequences);
stringsSequences.clear();
System.out.println(stringsSequences + " " + stringsSequences.size());
}
}
System.out.println(stringsSequencesCollection.size());
System.out.println(stringsSequencesCollection.get(2).size());
System.out.println();
int maximalStringSequence = Integer.MIN_VALUE;
int index = 0;
ArrayList<String> currentStringSequence = new ArrayList<String>();
for (int i = 0; i < stringsSequencesCollection.size(); i++) {
currentStringSequence = stringsSequencesCollection.get(i);
System.out.println(stringsSequencesCollection.get(i).size());
if (stringsSequencesCollection.get(i).size() > maximalStringSequence) {
maximalStringSequence = stringsSequencesCollection.get(i).size();
index = i;
//System.out.println("\n" + index);
}
}
System.out.println(String.join(" ", stringsSequencesCollection.get(index)));
I think it should be work correct but there is a problem - the sub array list's count isn't correct: All the sub arrayList's size is 1 and for this reason the output is not correct. I don't understand what is the reason for this. If anybody can help me to fix the code I will be gratefull!
I think it is fairly straight forward just keep track of a max sequence length as you go through the array building sequences.
String input = "hi yes yes yes bye";
String sa[] = input.split(" ");
int maxseqlen = 1;
String last_sample = sa[0];
String longest_seq = last_sample;
int seqlen = 1;
String seq = last_sample;
for (int i = 1; i < sa.length; i++) {
String sample = sa[i];
if (sample.equals(last_sample)) {
seqlen++;
seq += " " + sample;
if (seqlen > maxseqlen) {
longest_seq = seq;
maxseqlen = seqlen;
}
} else {
seqlen = 1;
seq = sample;
}
last_sample = sample;
}
System.out.println("longest_seq = " + longest_seq);
Lots of issues.
First of all, when dealing with the last string of the list you are not actually printing it before clearing it. Should be:
if(i == strings.length - 1)
//...
System.out.println(stringsSequences + " " + stringsSequences.size());
stringsSequences.clear();
This is the error in the output.
Secondly, and most importantly, when you do stringsSequencesCollection.add you are adding an OBJECT, i.e. a reference to the collection. When after you do stringsSequences.clear(), you empty the collection you just added too (this is because it's not making a copy, but keeping a reference!). You can verify this by printing stringsSequencesCollection after the first loop finishes: it will contain 3 empty lists.
So how do we do this? First of all, we need a more appropriate data structure. We are going to use a Map that, for each string, contains the length of its longest sequence. Since we want to manage ties too, we'll also have another map that for each string stores the leftmost ending position of the longest sequence:
Map<String, Integer> lengths= new HashMap<>();
Map<String, Integer> indexes= new HashMap<>();
String[] split = input.split(" ");
lengths.put(split[0], 1);
indexes.put(split[0], 0);
int currentLength = 1;
int maxLength = 1;
for (int i = 1; i<split.length; i++) {
String s = split[i];
if (s.equals(split[i-1])) {
currentLength++;
}
else {
currentLength = 1;
}
int oldLength = lengths.getOrDefault(s, 0);
if (currentLength > oldLength) {
lengths.put(s, currentLength);
indexes.put(s, i);
}
maxLength = Math.max(maxLength, currentLength);
}
//At this point, youll have in lengths a map from string -> maxSeqLengt, and in indexes a map from string -> indexes for the leftmost ending index of the longest sequence. Now we need to reason on those!
Now we can just scan for the strings with the longest sequences:
//Find all strings with equal maximal length sequences
Set<String> longestStrings = new HashSet<>();
for (Map.Entry<String, Integer> e: lengths.entrySet()) {
if (e.value == maxLength) {
longestStrings.add(e.key);
}
}
//Of those, search the one with minimal index
int minIndex = input.length();
String bestString = null;
for (String s: longestStrings) {
int index = indexes.get(s);
if (index < minIndex) {
bestString = s;
}
}
System.out.println(bestString);
Below code results in output as you expected:
public static void main(String[] args) {
System.out.println("Please enter a sequence of strings separated by spaces:");
Scanner inputStringScanner = new Scanner(System.in);
String[] strings = inputStringScanner.nextLine().split(" ");
System.out.println(String.join(" ", strings));
List <ArrayList<String>> stringsSequencesCollection = new ArrayList<ArrayList<String>>();
List <String> stringsSequences = new ArrayList<String>();
//stringsSequences.add(strings[0]);
boolean flag = false;
for (int i = 1; i < strings.length; i++) {
if(strings[i].equals(strings[i - 1])) {
if(flag == false){
stringsSequences.add(strings[i]);
flag= true;
}
stringsSequences.add(strings[i]);
}
}
int maximalStringSequence = Integer.MIN_VALUE;
int index = 0;
List <String> currentStringSequence = new ArrayList<String>();
for (int i = 0; i < stringsSequencesCollection.size(); i++) {
currentStringSequence = stringsSequencesCollection.get(i);
System.out.println(stringsSequencesCollection.get(i).size());
if (stringsSequencesCollection.get(i).size() > maximalStringSequence) {
maximalStringSequence = stringsSequencesCollection.get(i).size();
index = i;
//System.out.println("\n" + index);
}
}
System.out.println(stringsSequences.toString());

Swapping string position in Arraylist java

I have a sentence: Humpty Dumpty sat on a wall.
I want the strings to swap positions such that : Dumpty Humpty on sat wall a.
So the code that I wrote is following :
import java.util.*;
public class Swap{
public static void main(String []args) {
ArrayList<String> sentence = new ArrayList<String>();
sentence.add("Humpty");
sentence.add("Dumpty");
sentence.add("sat");
sentence.add("on");
sentence.add("a");
sentence.add("wall");
int size = sentence.size() ; // for finding size of array list
int numb ;
if(size%2 == 0) {
numb = 1;
}
else {
numb = 0;
}
ArrayList<String> newSentence = new ArrayList<String>();
if(numb == 1) {
for(int i = 0; i <= size ; i = i+2) {
String item = sentence.get(i);
newSentence.add(i+1, item);
}
for(int i = 1; i<=size ; i = i+2) {
String item2 = sentence.get(i);
newSentence.add(i-1, item2);
}
System.out.println(newSentence);
}
else {
System.out.println(sentence);
}
}
}
The code is compiling correct but when I run it, its giving an error.
What i understand of this is that I am adding strings to the array list leaving positions in between. Like adding at position 3 without filling position 2 first. How do I overcome this problem ?
You're correct about your problem - you're trying to insert an element into index 1 before inserting an element at all (at index 0), and you get an IndexOutOfBoundsException.
If you want to use your existing code to achieve this task, simply have just one loop as such:
if(numb == 1) {
for(int i = 0; i < size-1 ; i = i+2) {
String item = sentence.get(i+1);
newSentence.add(i, item);
item = sentence.get(i);
newSentence.add(i+1, item);
}
}
If you want to be a bit more sophisticated a use Java's built-in functions, you can use swap:
for(int i = 0; i < size-1 ; i = i+2) {
Collections.swap(sentence, i, i+1);
}
System.out.println(sentence);
You can initilize newSentence using:
ArrayList<String> newSentence = new ArrayList<String>(Collections.nCopies(size, ""));
This will let you access/skip any position in between 0 and size. So you can keep your rest of the code as it is.
just remember all index are being populated with empty String here.
That is because:
for(int i = 0; i <= size ; i = i+2) {
String item = sentence.get(i);
newSentence.add(i+1, item);//Here you will face java.lang.IndexOutOfBoundsException
}
for(int i = 1; i<=size ; i = i+2) {
String item2 = sentence.get(i);
newSentence.add(i-1, item2);//Here you will face java.lang.IndexOutOfBoundsException
}
instead of this, try following code:
if(numb == 1) {
for(int i = 0; i < size-1 ; i +=2) {
Collections.swap(sentence, i, i+1);
}
}

How can I avoid the user to add a repeated int value to an array?

First of all, I'm trying to do this using only simple conditions since I don't know how to use Hashmaps.
Ok, here is what I got so far, but I got stuck. Do you guys know a way in which I can compare an int to all the ints in an array?
public void rep() throws IOException {
for (int i = 0; i < arr.length; i++) {
System.out.println("Enter the value for the position # " + (1+i) + " of the array.");
int lol = Integer.parseInt(entrada.readLine());
if(!Arrays.Equals(arr[i], lol))
arr[i] = Integer.parseInt(entrada.readLine());
}
}
You can try this:
boolean repeat = false;
for(int j=0; j<i; j++ )
{
if(arr[j] == lol)
{
repeat = true;
break;
}
}
if(!repeat)
arr[i] = Integer.parseInt(entrada.readLine());
you can use the following method
for(i=0;i<intArray.length;i++){
if(intValue==intArray[i])
{ //write codes for if }
else{
// write codes for else }
You can do
java.util.Arrays.asList(arr).contains(lol)
what the above function is doing it coverts the array to list and the apply contains method to check if element is present

JAVA: Word game query

Hello my fellow programmers!
I have this code so far:
public class Levels {
int cLevel;
public void newGame() {
boolean newGame = true;
if (newGame) {
cLevel = 1;
List<String> list = new ArrayList<String>();
try {
BufferedReader bf = new BufferedReader(new FileReader(
"src/WordGuess/ReadFile/LevelFiles/Level_" + cLevel
+ ".txt"));
String cLine;
while ((cLine = bf.readLine()) != null) {
list.add(cLine);
}
String words[] = new String[list.size()];
words = list.toArray(words);
System.out
.println("These are your help letters so you can beat that level: "
+ words[0]);
for (int i = 1; i < words.length; i++) {
char[] replaceChar = words[i].toCharArray();
for (int x = 0; x < replaceChar.length; x++) {
replaceChar[x] = '*';
}
String replacement = new String(replaceChar);
System.out.println("\f" + replacement);
}
System.out.println("\t Score: " + Score(0) + ";\t Lives: "
+ Lives(5) + ";");
System.out.println("\n Enter Word:");
System.in.read();
} catch (Exception e) {
System.out
.println("Oh! Something went terribly wrong. A team of highly trained and koala-fied koalas have been dispatched to fix the problem. If you dont hear from them please restart this program.");
e.printStackTrace();
}
}
}
private int Lives(int lives) {
int wrongTries = 0;
boolean correctWord;
int counter = 0;
String livesForm[] = new String[lives];
// for (int i = 0; i == lives; i++) {
// livesForm[i] = "♥";
// }
return lives;
}
private int Score(int score) {
return score;
}}
So my query is as follows.
I want to show the lives as the heart symbol and still keep the integer value of it for functioning purposes. So as shown in my code example 5 lives to be represented by 5 hearts but still keep the int lives value of 5. As shown also in my example i also tried with an array of strings the size of the integer value 'lives' and to be replaced by hearts. As far as i ran the code no error was displayed whatsoever so i would assume that the array has been populated but i couldn't figure out how to display the array in the console as "Lives: ♥♥♥♥♥".
I have tried with the regular:
System.out.println(livesForm[i]);
But it did not display anything. I don't know if i have structured my question perfectly clear. I will be glad if any of you fellas can give me an advice or hint. Thank you for spending time on this question!
Why not:
public String getLivesAsString(int lives) {
StringBuilder sb = new StringBuilder(lives);
for(int i = 0; i < lives; i++) {
sb.append("♥");
}
return sb.toString();
}
?
Not sure why you need an array to display an amount of '♥'-symbols defined by an integer?

Categories