Compare the index of 2 String arrays with different values Java - java

I have 2 parallel arrays: the first contains State Names, the second Capitals of the states.
I'm making a quiz that randomly generates a State then asks the user to enter the Capital of the state. Once the input is received I want to call a method to check if the index of the capital entered is the same as the index of the state it goes with.
ie: stateArray[0] = "New York" and capitalArray[0] = "Albany".
Check Answer Method
public static void checkAnswer(String[]stateArray, String capitalArray, String answer)
{
int index;
for (int i = 0; i < capitalArray.length; i++){
if(capitalArray[i].equalsIgnoreCase(answer)){
index = i;
}
}
if(capitalArray[index] == stateArray[index])
{
System.out.println("correct");
}
else
{
System.out.println("incorrect");
}
}
I know the second if statement is wrong. How can I compare the two arrays using the index where the users answer was found in the capitalArray?

boolean checkAnswer(String[] stateArray, String[] capitalArray, String displayedState, String answer) {
for (int i = 0; i < stateArray.length; i++) {
if (stateArray[i].equals(displayedState) && capitalArray[i].equals(answer)) {
return true;
}
}
return false;
}
Or something. The key is you need to pass in something to represent the state you displayed.

You need to keep track of the index that holds the State displayed to the user. For example, the way your code is written now gives the user the ability to get a right answer by giving a wrong answer. Take this example as explanation:
string[] stateArray = {"New York", "California"};
string[] capitalArray = {"Albany", "Sacramento"};
If you were to show "New York" as the question and the user happens to answer "Sacramento" your code would display correct.
You also need a case in which the answer does not match any of the capitals in the array. One way of doing this to implement in your code is to initiate the index to -1.
int index = -1;
Once you finish the for loop check if index is -1 and display "Your answers is not a valid State" or something along those lines.
Maybe use a HashMap, I am not completely familiar with Java it appears to be the similar to a Dictionary in Python. Dictionary object has great performance.

Since you know what state you asked about you should know its array index as well. As you see below both arrays are declared as class variables.
... class Quiz {
private String[] states = new String[50];
private String[] capitals = new String[50];
... method to fill both arrays with the correct data
public static void checkAnswer(int question, String answer)
{
if(capitalArray[question].equalsIgnoreCase(answer)){
{
System.out.println("correct");
}
else
{
System.out.println("incorrect");
}
}
}
It's better to have checkAnswer method's return type as Boolean, but I left it your way.

An alternate implementation in Java would be to use a Map instead of two arrays.
Map<String,String> stateCapitals = new HashMap<String,String>();
stateCaptitals.put("New York", "Albany");
then you can check the map with
public voic checkAnswer(String chosenState, String chosenCapital) {
if (stateCapitals.get(chosenState).equals(chosenCapital) {
System.out.println("you are correct!");
}
}
This does not do it with 2 parallel arrays, but it is a better implementation if your real concern is the type of data you mentioned, and not the arrays themselves.

Try this function it return array:-
public static String[] numSame (String[] list1, String[] list2)
{
int same = 0;
for (int i = 0; i <= list1.length-1; i++)
{
for(int j = 0; j <= list2.length-1; j++)
{
if (list1[i].equals(list2[j]))
{
same++;
break;
}
}
}
String [] array=new String[same];
int p=0;
for (int i = 0; i <= list1.length-1; i++)
{
for(int j = 0; j <= list2.length-1; j++)
{
if (list1[i].equals(list2[j]))
{
array[p]= list1[i]+"";
System.out.println("array[p] => "+array[p]);
p++;
break;
}
}
}
return array;
}

Related

Why my logic for the below code doesn't work?

Can anyone explain me why my code doesn't work, where I am going wrong here?
I have written this code for counting the number 0-9 in an integer in java. If possible please help me with the best solution too.
Well I know it can be efficiently solved by using hash table but I'm looking for a solution which can be understandable by a newbie.
import java.util.*;
class CountNo {
public static void main(String args[] ) {
Scanner a = new Scanner(System.in);
String s = a.next();
char[] b = s.toCharArray();
int S_len = s.length();
int[] count = {0,0,0,0,0,0,0,0,0,0};
for(int i=0;i<S_len;i++)
{
for(int j=0;j<=9;j++)
{
if(b[i]==j)
{
count[j]+=1;
break;
}
}
}
for(int i=0;i<=9;i++)
{
System.out.println(i+" "+count[i]);
}
}
}
because char '0' != 0, it has code 48, so you need to change
if(b[i]==j)
into
if(b[i]-'0'==j)
or you could simplify logic, like:
for(int i = 0; i < S_len; i++)
count[b[i] - '0'] += 1;
You could use a map, in which the key is the digit and the value is the count.
You can learn more about maps here: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html but essentially, a map is a Java object which relates a "key" to a "value", and does not allow duplicates. This is useful if you are trying to keep track of how many times a "key" (in this case, a digit) appears in a string or array.
if(b[i]==j)
{
count[j]+=1;
break;
}
You compare char to int. Try this instead:
if(Character.getNumericValue(b[i]) == j){
count[j]+=1;
break;
}

Java: Remove an item from existing String Array

I've scoured a couple of the SOF threads but can't seem to find the answer I'm looking for. Most of them provide an answer with code that's beyond the scope of what I have learned thus far.
I've tried quite a few different things and can't get this to work the way I need it to.
The program is supposed to take the given array, read it, find the given toRemove item, and re-print the array without the toRemove item.
I believe my issue is within the removeFromArray method
public static void main(String[] args)
{
String[] test = {"this", "is", "the", "example", "of", "the", "call"};
String[] result = removeFromArray(test, "the");
System.out.println(Arrays.toString(result));
}
public static String[] removeFromArray(String[] arr, String toRemove)
{
int newLength = 0;
for(int i = 0; i < arr.length; i++)
{
if(arr[i].contains(toRemove))
{
newLength++;
}
}
String[] result = new String[arr.length-newLength];
for(int i = 0; i < (result.length); i++)
{
if(arr[i].contains(toRemove))
{
}
else
{
result[i] = arr[i];
}
}
return result;
}
This is an assignment in my java class and we have not learned Lists (one of the answers I stumbled upon in my googling) yet so that is not an option for me.
As it is now, it should be outputting:
[this, is, example, of, call]
Currently it is outputting: [this, is, null, example, of]
Any and all help will be much appreciated!
You need 2 indices in the second loop, since you are iterating over two arrays (the input array and the output array) having different lengths.
Besides, newLength is a confusing name, since it doesn't contain the new length. It contains the difference between the input array length and the output array length. You can change its value to match its name.
int newLength = arr.length;
for(int i = 0; i < arr.length; i++)
{
if(arr[i].contains(toRemove))
{
newLength--;
}
}
String[] result = new String[newLength];
int count = 0; // count tracks the current index of the output array
for(int i = 0; i < arr.length; i++) // i tracks the current index of the input array
{
if(!arr[i].contains(toRemove)) {
result[count] = arr[i];
count++;
}
}
return result;
There's the error that #Eran pointed out in your code, which can solve your problem. But I'm going to discuss another approach.
For now, you're first iterating over the entire array to find the number of occurrences to remove, and then, you're iterating over the array to remove them. Why don't you just iterate over the array, just to remove them. (I know, your first loop is helping you to determine the size of the output array, but you don't need that if you use some List like ArrayList etc.)
List<String> resultList = new ArrayList<String>();
for(int i = 0; i < arr.length; i++)
{
if(!arr[i].contains(toRemove))
{
resultList.add(arr[i]);
}
}
And you can return the resultList, but if you really need to return an array, you can convert the resultList to an array like this:
String [] resultArray = resultList.toArray(new String[resultList.size()]);
And then return this array. See this approach live here on ideone.
Try this Java8 version
List<String> test = Arrays.asList("this", "is", "the", "example", "of", "the", "call");
test.stream()
.filter(string -> !string.equals("the"))
.collect(Collectors.toList())
.forEach(System.out::println);
You can use Java Stream instead, it will give you the expected result and also your code will be clearer and really smaller.
See the method below I wrote that solves your problem.
public static String[] removeFromArray(String[] arr, String toRemove) {
return Arrays.stream(arr)
.filter(obj -> !obj.equals(toRemove))
.toArray(String[]::new);
}
If you're unfamiliar with java Stream, please see the doc here
The following code removes all occurrences of the provided string.
Note that I have added few lines for validate the input, because if we pass a null array to your program, it would fail. You should always validate the input in the code.
public static String[] removeFromArray(String[] arr, String toRemove) {
// It is important to validate the input
if (arr == null) {
throw new IllegalArgumentException("Invalid input ! Please try again.");
}
// Count the occurrences of toRemove string.
// Use Objects.equals in case array elements or toRemove is null.
int counter = 0;
for (int i = 0; i < arr.length; i++) {
if (Objects.equals(arr[i], toRemove)) {
counter++;
}
}
// We don't need any extra space in the new array
String[] result = new String[arr.length - counter];
int resultIndex = 0;
for (int i = 0; i < arr.length; i++) {
if (!Objects.equals(arr[i], toRemove)) {
result[resultIndex] = arr[i];
resultIndex++;
}
}
return result;
}

How do I sort an array of strings alphabetically in java?

I'm new to programming/coding and have been stuck on a project in school for a few days now. The goal is to take an array full of words (each position is a different word) and sort it alphabetically. I've tried doing some research on stack overflow already, but I'm having a bit of trouble following some of the examples I've found. The class and driver (I'm using a two part setup if you will) both compile fine, no problems there. The problem occurs when I try to use alphaSort from my driver. I receive a null pointer exception for the line marked below. I've had some trouble with these exceptions in the past, so I'm sure it's something small I'm overlooking. As stated however, I'm not yet fluent enough in the java syntax to catch a small error like that.
I figured I should just include the entire method in-case my error is something in the beginning, before the sorting part. What I have so far (i found this on Stack overflow):
public void alphaSort()
{
String alphaList[] = new String[wordList.size()];
int count=0;
//puts wordList into alphaList for easier sorting
while(count<wordList.size()-1)
{
alphaList[count]=wordList.get(count);
count++;
}
int shortestStringIndex;
//sort begins here
for(int j=0; j<alphaList.length -1; j++)
{
shortestStringIndex = j;
for(int i=j+1; i<alphaList.length; i++)
{
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim())<0) //null pointer exception points here
{
shortestStringIndex = i;
}
}
if(shortestStringIndex !=j)
{
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]=temp;
}
}
//prints out results
count=0;
while(count<alphaList.length)
{
System.out.println(alphaList[count]);
alphaOut.print(alphaList[count]);
count++;
}
}
Any help would be greatly appreciated. Please be as thorough as possible in giving an answer (as i said, I'm a bit of a java newbie). Thanks :)
edit: to test for null values (which i assume are spots in my array list that are blank) i made the following method:
public void isNull()
{
int count=0;
while(count<wordList.size()-1)
{
if((wordList.get(count)).equals(""))
{
System.out.println("null");
break;
}
else
{
System.out.println("nothing yet");
}
count++;
}
}
the while loop never broke early, my method ran to completion.
You need to update the first while loop to match:
while(count < wordList.size()) {
alphaList[count] = wordList.get(count);
count++;
}
You aren't copying over every index of the list to the array, which means that when it goes to check the last index, it cannot find a value (NullPointerException).
Edit:
Here's my full test class that works:
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
new Test();
}
private ArrayList<String> wordList = new ArrayList<String>();
public Test() {
wordList.add("Test");
wordList.add("Bee");
wordList.add("Pig");
wordList.add("Dog");
alphaSort();
}
public void alphaSort() {
String[] alphaList = new String[wordList.size()];
int count = 0;
while(count < wordList.size()) {
alphaList[count] = wordList.get(count);
count++;
}
int shortestStringIndex;
for(int j = 0; j < alphaList.length - 1; j++) {
shortestStringIndex = j;
for(int i = j + 1; i < alphaList.length; i++) {
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim()) < 0) {
shortestStringIndex = i;
}
}
if(shortestStringIndex != j) {
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]= temp;
}
}
count = 0;
while(count < alphaList.length) {
System.out.println(alphaList[count++]);
}
}
}
Output:
Bee
Dog
Pig
Test
Try this...
// sorting array
if(wordList.size()>0){
String alphaList[] = new String[wordList.size()];
//convert list to String array
alphaList= wordList.toArray(alphaList);
//sorting
Arrays.sort(alphaList);
}
........
// let us print all the elements available in wordList
if(wordList.size()>0){
for (String word: alphaList) {
System.out.println("word= " + word);
}
}
There is an error when you are copying your List to an array. It is inserting a null at the end of the list which is causing your NullPointerException. Here is the revised version that works. Instead of looping through the List and copying each item to the array(which is buggy) I just use the standard java method that is on a List to convert the List to an array.
public static void alphaSort()
{
String alphaList[] = wordList.toArray(new String[]{});
int shortestStringIndex;
//sort begins here
for(int j=0; j<alphaList.length -1; j++)
{
shortestStringIndex = j;
for(int i=j+1; i<alphaList.length; i++)
{
if(alphaList[i].trim().compareTo(alphaList[shortestStringIndex].trim())<0) //null pointer exception points here
{
shortestStringIndex = i;
}
}
if(shortestStringIndex !=j)
{
String temp = alphaList[j];
alphaList[j] = alphaList[shortestStringIndex];
alphaList[shortestStringIndex]=temp;
}
}
//prints out results
int count=0;
while(count<alphaList.length)
{
System.out.println(alphaList[count]);
alphaOut.print(alphaList[count]);
count++;
}
}
The problem is that you're adding wordList.size()-1 number of items into the array and the array size is wordList.size() which means that the last value in the array is null
For this while loop:
while (count<wordList.size()-1)
{
alphaList[count]=wordList.get(count);
count++;
}
you don't need to loop to wordList.size()-1 since you already do < instead of <=. You are stopping your loop at the second to last index and are thus not assigning a value to the last place in the array. Instead do while (count < wordList.size()) or while (count <= wordList.size()-1)

Print out strings from an arraylist in a given range java?

My method is supposed to print out all of the strings in between 2 strings in my ArrayList, exclusive of both the beginning string and the end string.
public void printRange(String beg, String end)
{
for(int i = 0; i < list.size(); i++)
{
}
}
String beg is the beginning string and String end is the last string. To further clear up, if I have an ArrayList containing the words "dog" "cat" "apple" "banana" "turtle", and I enter in "cat" and "turtle", the method should print out "apple" and "banana".
I know I should iterate through the list, but I'm lost as to where I go from there.
Edit: Sorry for posting 2 questions! I'll submit them differently next time.
Try using a flag to avoid one more N iteration.
public void printRange(String beg, String end)
{
boolean startPrinting = false;
for (int i = 0; i < list.size(); i++)
{
if (startPrinting) {
System.out.println(list.get(i));
}
if (list.get(i).equals(beg)) {
startPrinting = true;
} else if (list.get(i).equals(end)) {
break;
}
}
}
I would edit out the second question. You don't post two questions for one topic on SO.
Regarding your first question, you want to get the index of where the first string and the last string are found. Something like this:
public void printRange(String beg, String end)
{
int begIdx, endIdx;
for(int i = 0; i < list.size(); i++)
{
if (list[i].equals(beg)) {
begIdx = i;
}
if (list[i].equals(end)) {
endIdx = i;
}
}
for(int i = begIdx; i < endIdx; i++)
// Print range...
}
That's a quick and dirty implementation. You can do this in one traversal of the list.
You can also make use of the indexOf() method. I am not sure what you are up to, but bear in mind a List can contain duplicate keys. Consider using a Set instead.
package com.company;
import java.util.ArrayList;
import java.util.List;
public class Main {
private List<String> list = new ArrayList<String>();
{
list.add("dog");
list.add("cat");
list.add("apple");
list.add("banana");
list.add("turtle");
}
public void printRange(String beg, String end)
{
int start = list.indexOf(beg) + 1;
int finish = list.indexOf(end);
if (start <= 0 || start >= finish) return;
for(int i = start; i < finish; i++)
{
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
new Main().printRange("cat", "turtle");
}
}
I'd use a tiny state machine -
state 0 = beginning not found
state 1 = beginning found, end not found
state 2 = end found (or could go back to 0 if you want to look for beginning again)
You need relevant checks to change the state and only have to print stuff out when you're in state 1.
This way you only have to go through the list once instead of going through it (partially) to find beginning and end, and then going through it (partially) again to output required fields.

removing duplicated words from an array

I am trying to remove duplicated words from an array, and I keep getting null values. I'm not allowed to use java sorting methods so I have to develop my own. Here's my code:
public class Duplicate{
public static void main(String[] args){
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
removeDuplicate(test);
}
public static String[] removeDuplicate(String[] words){
boolean [] isDuplicate = new boolean[words.length];
int i,j;
String[] tmp = new String[words.length];
for (i = 0; i < words.length ; i++){
if (isDuplicate[i])
continue;
for(j = 0; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
tmp[i] = words[i];
}
}
}
for(i=0;i<words.length;i++)
System.out.println(tmp[i]);
return tmp;
}
}
I tried doing
if(words == null)
words == "";
But it doesn't work. I also want to return the tmp array with a new size.
For example, test array length = 9, after removing the duplicates,I should get a new array with a length of 7.Thank you for your help.
EDIT:
result i get:
a
b
abvc
abccc
null
bbc
ccc
abc
null
You're getting nulls because the result array contains fewer words than the input array. However, you're constructing the arrays of the same length.
You don't have to sort to solve this problem. However, if you're not allowed to use the tools provided by java.utils, then this is either a poorly contrived test question or whomever told you not to use the Java utility classes is poorly informed.
You can solve without sorting by doing (assuming Java 1.5+):
public class Duplicate {
public static void main(String[] args) {
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
String[] deduped = removeDuplicate(test);
print(deduped);
}
public static String[] removeDuplicate(String[] words) {
Set<String> wordSet = new LinkedHashSet<String>();
for (String word : words) {
wordSet.add(word);
}
return wordSet.toArray(new String[wordSet.size()]);
}
public static void print(String[] words) {
for (String word : words) {
System.out.println(word);
}
}
}
The output will be:
a
b
abvc
abccc
bbc
ccc
abc
I would go for hashset to remove duplicates, it will remove duplicates since hash function for the same string will give same value, and duplicates will be eliminated. Then you can convert it to a string.
I would recommend doing this with a different approach. If you can use an ArrayList, why not just create one of those, and add the non-duplicate values to it, like this:
ArrayList<String> uniqueArrayList = new ArrayList<String>();
for(int i = 0; i < words.length; i++){
if(!uniqueArrayList.contains(words[i])){ // If the value isn't in the list already
uniqueArrayList.add(words[i]);
}
}
Now, you have an array list of all of your values without the duplicates. If you need to, you can work on converting that back to a regular array.
EDIT
I really think you should use the above option if you can, as there is no clean or decently efficient way to do this only using arrays. However, if you must, you can do something like this:
You can use the code you have to mark values as null if they are duplicates, and also create a counter to see how many unique values you have, like this:
int uniqueCounter = 0;
for(int i = 0; i < isDuplicate.length; i++){
if(!isDuplicate[i]){
uniqueCounter++;
}
}
Then, you can create a new array of the size of unique items, and loop through the words and add non-duplicate values.
String[] uniqueArray = new String[uniqueCounter];
int uniqueIndex = 0;
int wordsIndex = 0;
while(index < uniqueArray.length){
// Check if words index is not a duplicate
if(!isDuplicate[wordsIndex]){
// Add to array
uniqueArray[uniqueIndex] = words[wordsIndex];
uniqueIndex++; // Need to move to next spot in unique.
}
// Need to move to next spot in words
wordsIndex++;
}
Again, I HIGHLY recommend against something like this. It is very poor, and pains me to write, but for the sake of example on how it could be done using an array, you can try it.
I don't have the time to write functioning code, but I would reccomend to first sort the array using Arrays.sort(stringArray) and then loop throug the array coparing one string to the previous. Strings that match the previous one are duplicates.
Note: This method is probably not the fastest one and though only should be used on small arrays or in tasks where performance does not matter.
What about this approach?
public static String[] removeDuplicate(String[] words){
// remember which word is a duplicate
boolean[] isDuplicate = new boolean[words.length];
// and count them
int countDuplicate = 0;
for (int i = 0; i < words.length ; i++){
// only check "forward" because "backwards checked" duplicates have been marked yet
for(int j = i + 1; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
countDuplicate++;
}
}
}
// collect non-duplicate strings
String[] tmp = new String[words.length - countDuplicate];
int j = 0;
for (int i = 0; i < isDuplicate.length; i++) {
if (isDuplicate[i] == false) {
tmp[j] = words[i];
j++;
}
}
// and return them
return tmp;
}

Categories

Resources