I have to compare two String arrays with integer values separated by "#" input by the user as follows:
Input 1: Size of the array:
3
Input 2: (Array 1)
1#4#5
3#6#7
5#8#9
Input 2: (Array 2)
1#3#5
4#6#7
5#7#9
They contain the same no. of integer strings per line as specified by the user input array size. For eg: the 1st line of Array 1 = 1#4#5 = 3 integer strings.
In case, the array inputs are blank in any line, the output should be "invalid".
The output should be "yes" if the integer values in both the arrays are same irrespective of their position in the array i.e. if they are equivalent, otherwise the output should be "no".
My code passes very few test cases and mostly gives the correct output only when the two arrays are transpose of each other (when seen from the input format). It does not give the correct output when all the integer strings in both the arrays are same irrespective of their positions in the array.
eg. 1: Test case passed:
The output for the arrays in the example above is yes
eg.2: Test case failed:
Input 1: Size of the array:
2
Input 2: (Array 1)
1#6
3#4
Input 2: (Array 2)
6#3
4#1
Output: no
Here is my code:
import java.util.Scanner;
import java.util.Arrays;
public class StringComparison
{
public static void main (String[]args)
{
Scanner input = new Scanner (System.in);
// Input the array size
System.out.println("Enter the array size:");
int size = input.nextInt();
input.nextLine();
String[] s1 = new String[size];
String[] s2 = new String[size];
// Input 1st array elements
System.out.println("Enter the 1st array elements:");
for (int i=0;i<size; i++)
{
s1[i]= input.nextLine();
}
// Input 2nd array elements
System.out.println("Enter the 2nd array elements:");
for (int i=0;i<size; i++)
{
s2[i]= input.nextLine();
}
// Check for equivalence
System.out.println(equivalent (size, s1, s2));
}
public static String equivalent (int input1, String[]input2, String[]input3)
{
String result =null;
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
char []b1 = new char[input1*input1];
char[]b2 = new char[input1*input1];
int[] num1 = new int[input1*input1];
int[] num2 = new int[input1*input1];
for (int i=0; i<input1;i++)
{
String[] a1 = input2[i].split("#");
// if the user inputs are less or more than required
try
{
for (int j=0;j<input1;j++)
sb1.append (a1[j]);
}
catch (java.lang.ArrayIndexOutOfBoundsException e)
{
result ="invalid";
return result;
}
}
for (int i=0; i<input1;i++)
{
String[] a2 = input3[i].split("#");
// if the user inputs are less or more than required
try
{
for (int k=0;k<input1;k++)
sb2.append (a2[k]);
}
catch (java.lang.ArrayIndexOutOfBoundsException e)
{
result ="invalid";
return result;
}
}
// Storing the contents of the StringBuilder objects in a char array
sb1.getChars (0,((input1*input1)-1),b1,0);
sb2.getChars (0,((input1*input1)-1),b2,0);
// Converting the elements of the char array into integers and storing it in an int array
for (int p=0; p<((input1*input1)-1);p++)
{
num1[p] = Character.digit( b1[p],(input1*input1)-1);
}
// Converting the elements of the char array into integers and storing it in an int array
for (int q=0; q<((input1*input1)-1);q++)
{
num2[q] = Character.digit( b2[q],(input1*input1)-1);
}
// Sorting the two integer arrays
Arrays.sort (num1);
Arrays.sort (num2);
if (Arrays.equals (num1,num2))
{
result = "yes";
}
else
{
result ="no";
}
return result;
}
}
i have rewritten your equivalent method. i hope its okay to use ArrayList.
private static String equivalent(String[] s1, String[] s2) {
ArrayList<Integer> num1 = new ArrayList<Integer>();
ArrayList<Integer> num2 = new ArrayList<Integer>();
for (String str : s1) {
String[] storage = str.split("#");
for (String st : storage) {
num1.add(Integer.parseInt(String.valueOf(st)));
}
}
for (String str : s2) {
String[] storage = str.split("#");
for (String st : storage) {
num2.add(Integer.parseInt(String.valueOf(st)));
}
}
Collections.sort(num1);
Collections.sort(num2);
if (num1.equals(num2)) {
return "yes";
} else {
return "no";
}
}
this does what you want to achieve with fewer code. if you need help understand or have any other questions feel free to ask
The logic you are using to make the integer array is wrong and it produced invalid entries.Try printing the array values.All the test cases will fail.
Try below to convert the the char into the integer
num2[q] = Integer.parseInt(String.valueOf(b2[q]));
num1[p] = Integer.parseInt(String.valueOf(b1[p]));
Note:Example 1 should have been "NO". There is no 8 in the second input.
Related
Hi guys! =)
I'm new to Java, currently, I'm learning arrays and loops. I have an interesting homework task that I am very confused about.
And I don't know what to do with this one. So I need your advice.
Create a public String getCheapStocks(String[] stocks) method in it. It takes an array of strings as input. Each line consists of the name of the product and its price, separated by a single space.
The method returns a string - a list of product names whose price is less than 200.
And the getCheapStocks(new String[] {"gun 500", "firebow 70", "pixboom 200"}) returns "firebow".
There is only for loop can be used.
I found a method that can split a string:
String text = "123 456"
String[] parts = text.split(" ")
int number1 = Integer.parseInt(parts[0]) //123
int number2 = Integer.parseInt(parts[1]) //456
But when I have String "gun 500" I can only split it in two String. And I can't compare it to 200. My code is a mess and it does nothing.
I would really appreciate any tips or advice, thanks in advance!
public static String getCheapStocks(String[] stocks) {
//MESS!
int max = 200;
for(int i = 0; i < stocks.length; i++) {
String txt = stocks[i];
String[] parts = txt.split(" ");
int number1 = Integer.parseInt(parts[0]);
int number2 = Integer.parseInt(parts[1]);
if(number1 < max) {
}
}
}
public static void main(String[] args) {
//returns "firebow"
System.out.println(getCheapStocks(new String[] {"gun 500", "firebow 70", "pixboom 200"}));
}
}
Since your input is in format of "<stock> <price>", after splitting this into 2 parts, you have to convert only the second part to an integer, otherwise you will get an exception.
public static String getCheapStocks(String[] stocks) {
// Use a StringBuilder to hold the final result
StringBuilder result = new StringBuilder();
for (String stock : stocks) {
String[] parts = stock.split(" ");
// If the price is lower than 200, append part[0] (stock name) to the result
if (Integer.parseInt(parts[1]) < 200) {
result.append(parts[0]).append(" "); // Append also a space character for dividing the stocks
}
}
// Strip the space from the end
return result.toString().trim();
}
public static String getCheapStocks(String[] stocks) {
int maxPrice = 200;
List<String> results = new ArrayList<>();
for (String txt : stocks) {
String[] parts = txt.split(" ");
String stockName = parts[0];
int price = Integer.parseInt(parts[1]);
if (price < maxPrice) {
results.add(stockName);
}
}
return String.join(" ", results);
}
I'm trying to replicate a DFA/NFA machine with printing transitions.
And am reaching errors when attempting to access values from my preset array and assign them to the newState variable.
So far I've tried moving variables within scope bodies, re-assigning variables and separating the try catch function to ensure the values of binaryValue and state are actually being correctly set.
The exception that occurs is array out of bounds. However i don't see what values requested are out of bounds.
Any help and advice would be appreciated
public class BinaryStringChecker {
private static boolean checker;
public static void main(String[] args) {
//user inputed variable
String userValue;
//checker for binary values variable
checker = false;
//NFA/DFA start State
int state = 0;
//transition array
int stateArray [][] = {{1,0},{2,0},{5,3},{4,4},{5,3},{6,4},{6,6}};
//User input
Scanner usersInput = new Scanner (System.in);
//Introduction
System.out.println("Implimented DFA, will accept binary strings over alphabet Σ= {0, 1} that contain two pairs of adjacent 0’s separated by an even number of alphabet symbols.");
//do while to check if values only consist of 0s and 1s
do{
System.out.println("Please enter desired string: ");
userValue = usersInput.next();
if (userValue.matches("[01]+")) {
System.out.println("Checking "+userValue);
checker = true;
usersInput.close();
}
else {
System.out.println("Thats not a binary number");
}
}
while (checker == false);
//assigning users input value
String str = userValue;
//taking binary list from STL class
STL.StringtoList(str);
//assigning list
List<Character>
chars = STL.StringtoList(str);
//getting binary string length
int stringLength;
stringLength = chars.size();
// Print the list of characters
System.out.println(chars);
//sequential iteration through users binary string
for (int i=0; i<stringLength; i++) {
//taking value from position in list
Character binaryValue = chars.get(i);
try {
int newState = stateArray[state][binaryValue];
state = newState;
System.out.println("Current state:"+state);
}
catch(Exception e) {
System.out.println("Somethings wrong here 1");
}
}
}
}
The main question will be at the bottom. From the text file below, lets say the first integer is a, second is b, and third is c and so forth. the program takes a,b and c, parses them, puts them into myCalculations method which returns a string with two integers. The string is parsed, a and b are replaced the integers in said returned string, then the next iteration of the loop will take the new values for a and b, and integer d. This will continue until the end where a and b are printed to the user.
The input from a two text files is as follows:
The format of the text file is as follows:
200 345
36
45
36
21
Here is the reading in from the file, it works as intended, I put it here for context. tl;dr is results[] is an integer array for the first line. (int a and b)
public class conflictTrial
{
BufferedReader in;
public static void conflictTrial() throws FileNotFoundException
{
System.out.print('\u000c');
System.out.println("please enter the name of the text file you wish you import. Choose either costs.txt or lotsacosts.txt Nothing else");
Scanner keyboard = new Scanner(System.in);
String filename = keyboard.nextLine();
File file = new File(filename);
BufferedReader in = new BufferedReader(new FileReader(file));
String element1 = null;
try {
element1 = in.readLine();
}catch (Exception e) {
// handle exception
}
String[] firstLine = element1.split(" ");
Arrays.stream(firstLine).forEach(fl -> {
//System.out.println("First line element: \t\t\t" + fl);
});
int[] results = new int[100];
for (int i = 0; i < firstLine.length; i++)
{
try {
int stuff = Integer.parseInt(firstLine[i]);
results[i] = stuff;
}
catch (NumberFormatException nfe) {
// handle error
}
}
The bufferreader reads in the file, the for loop parses the integers into array results[]. Next, the remaining lines are parsed and method myCalculations is called:
String otherElement = null;
int[] aliveSoldiers = new int[100];
int [] things = new int [100];
int[] newResults = new int[100];
try {
while ((otherElement = in.readLine()) != null) { // main loop
System.out.println("Line to process:\t\t\t" + otherElement);
String[] arr = otherElement.split(" ");
for (int k = 0; k <arr.length; k++)
{
int thingsResult = Integer.parseInt(arr[k]);
things[k] = thingsResult;
System.out.println("number of days: \t\t\t"+things[k]);
aliveSoldiers[0] = results[0];
aliveSoldiers[1] = results[1];
String returnAliveSoliders = myCalculations(aliveSoldiers[0], aliveSoldiers[1], things[k]);
System.out.println("return soldiers alive: \t\t"+returnAliveSoliders);
String[] newItems = returnAliveSoliders.split(" ");
for (int f = 0; f < newItems.length; f++)
{
int newParse = Integer.parseInt(newItems[f]);
newResults[f] = newParse;
aliveSoldiers[0] = newResults[0];
aliveSoldiers[1] = newResults[1];
}
k++;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
Currently the code does the following: first of the main loop iteration takes integer a, b and c, second iteration takes the same integers a and b (200 and 345, the initial values) with integer d, the third iteration takes the same values for and a and b with integer e. I have attempted to address this issue with the following code:
aliveSoldiers[0] = newResults[0];
aliveSoldiers[1] = newResults[1];
I need to take the integers from the method myCalculations (parsed in the k-modifier loop), and overwrite them into aliveSoldiers[0] and aliveSoldiers [1] so the program reads the next line, takes the new integers, and continues until there are no more days remaining.
I honestly haven't understood what the whole exercise should do, but the code You enlighted could be wrong due to the indexes You use: those indexes are always 0 and 1, even if cycles are performed through some other indexes. At the end of the second code snippet, the f-for modify the array "newResults" at the increasing index "f", but that array is read always at the same index: 0 and then 1. So, if "f" gets higher values than "1" then the "aliveSoldiers"'s elements are left unchanged.
In particular, aliveSoldiers is modified only on the first two indexes, the other indexes are not used at all.
Do you need a stack-like or queue-like behaviour?
I am trying to create an array that reads string tokens from standard input, and places them in an array, and then prints the words out, until it reaches a specific word. For example, let's say I wanted my array to read a series of words until it reached the word "okay" from std in, print out each word, and then terminate before printing out "okay". The length of this array will be unknown, so I am confused on how to do this.
String s = sc.next();
String[] copy = new String[???];
for( int i = 0; i < copy.length; i++ ){
copy[i] = sc.next();
}
Something like:
String s = sc.next();
ArrayList<String> copy = new ArrayList<String>();
while(!s.equals("okay")){
copy.add(s);
s = sc.next();
}
for (String n : copy){
System.out.println(n);
}
If you don't want to use any list at all, then this becomes impossible. This is simply because array size needs to be defined at the time the array object is created.
So with this constraint you can have a large integer and declare an array of that size.
Final int MY_LARGE_CONST = 3000;
...
String[] tokens = new String[MY_LARGE_CONST]...
This is wasteful since it takes more memory and will fail if you have more tokens than the constant.
Alternaely if you are ok with lists and not ok with iterating over that for actual processing, then u can put the tokens in an ArrayList and once they are all collected, call the toArray method on the ArrayList object.
It's my code Without using ArrayList.
import java.util.Scanner;
import java.util.StringTokenizer;
public class Sample {
public static void main(String[] args) {
Scanner sc = new Scanner(System. in );
String line = sc.nextLine();
StringTokenizer st = new StringTokenizer(line);
int len = st.countTokens();
String[] array = new String[len];
for (int idx = 0; idx < len; idx++) {
array[idx] = st.nextToken();
}
for (String str: array) {
System.out.println(str);
}
}
}
The user is allowed to play with an array of strings. They can add strings to the array, remove strings from the array, search for strings in the array, and eventually they will be able to sort the array. The sorting is what is messing me up. I've tried a few different approaches. The first approach was to convert the array into an ArrayList and use Collections to sort the ArrayList, which would be converted back into the static class array. It doesn't work. The second approach I tried was to iterate through the array and try to sort only the strings added by the user instead of everything in the array (since there are some null values in the array). Perhaps I should iterate through the array and then store the non-null values into a new array that I can then sort? But what if I want to add more strings after sorting the new array? That's why I stopped with the second solution. The third attempt was to use Arrays.sort() on my array but for some reason it does not work.
Here is the exception:
Exception in thread "main" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at testingSearch.sortArray(testingSearch.java:93)
at testingSearch.main(testingSearch.java:42)
Here is my code:
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class testingSearch {
static String[] strArray;
static {
strArray = new String[5];
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(true){
System.out.println("1. Add string to the string array.");
System.out.println("2. Remove string from the string array.");
System.out.println("3. Display strings in string array.");
System.out.println("4. Search the string array for a string.");
System.out.println("5. Sort the strings in the string array.");
int userChoice = 0;
userChoice = input.nextInt();
switch(userChoice) {
case 1:
addString();
break;
case 2:
removeString();
break;
case 3:
displayStrings();
break;
case 4:
searchArray();
break;
case 5:
sortArray();
break;
}
}
}
public static void addString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to add?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.add(userInput);
strArray = stringList.toArray(strArray);
}
public static void removeString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to remove?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.remove(userInput);
strArray = stringList.toArray(strArray);
}
public static void displayStrings(){
for (String s: strArray){
if (!(s == null)){
System.out.println(s);
}
}
}
public static void searchArray(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to search the array for?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
if (stringList.contains(userInput)){
System.out.println("The string array contains that string!");
}
else {
System.out.println("The string array does not contain that string...");
}
}
public static void sortArray(){
/*ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);*/
/*for (String s: strArray) {
if (!(s == null)){
Arrays.sort(strArray);
}
}*/
List<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);
//Arrays.sort(strArray);
}
}
The reason you're getting NullPointerExceptions can be explained by the javadoc for Arrays#sort() (emphasis mine):
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the Comparable interface.
Because Arrays.sort() expects Comparable elements and not null values, you end up with a NullPointerException when the method tries to call compareTo().
The fix-this-now way of solving this would be to simply make sure all null elements in your array are replaced with something non-null, such as "". So loop through your array at creation and after removing a String and set null elements to "". However, this solution probably wouldn't perform too well for your code, as it requires another loop after every String is removed, which could grow onerous. At least it won't require you to create a bunch of objects, due to the magic of the String pool, so it's a bit better than what you might do with a different object.
A better solution would be to simply use ArrayList<String> instead of a raw array; after all, you're already using one to manage addString() and removeString(), so you would have less converting from array to ArrayList and back to do. In addition, you wouldn't need to worry about NPEs when sorting (at least for your use case; adding null to a Collection would still result in NPEs when sorting).
You can also just use a raw array, but managing that would get kind of annoying, so I wouldn't recommend that. If you do it right you won't have to worry about NPEs though.
No problem! Here you go:
1. Create a new array
2. Insert items to that array, in the right order
public class sorter {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
String[] newArray = new String[array.length];
int index = 0;
for(int m = 0 ; m < newArray.length; m++){
String leastString = null;
int i = 0;
for(i = 0; i < array.length; i++){
if(leastString==null&&array[i]!=null){
leastString = array[i];
break;
}
}
for(int j = i+1; j < newArray.length; j++){
if(array[j]!=null){
if(array[j].compareTo(array[i])<0){
leastString = array[j];
i = j;
}
}
}
if(i==newArray.length)break;
newArray[m] = leastString;
array[i] = null;
}
for(String s : newArray){
System.out.println(s);
}
}
}
This prints:
:)
BYE
HI
SUP
null
EDIT: Another very simple way to solve this in a very effiecient manner, is to use ArrayList:
public class AClass {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
ArrayList<String> newArray = new ArrayList<String>();
for(String s : array){
if(s!=null){
newArray.add(s);
}
}
Collections.sort(newArray);
String[] retval = new String[newArray.size()];
retval = newArray.toArray(retval);
for(String s : retval){
System.out.println(s);
}
}
}
I guess the simple way of doing things really would be:
static String[] strArray;
static {
strArray = new String[5];
for(int i = 0, i < strArray.length; i++)
{
strArray[i] = "";
}
}
And then just call
Arrays.sort(strArray);
When you want to sort it. If that doesn't work, although I think it should; your initial approach would have been the following:
List<String> stringList = new ArrayList<String>();
for(int i = 0; i < strArray.length; i++)
{
stringList.add(strArray[i]);
}
Collections.sort(stringList);
strArray = stringList.toArray(new String[stringList.size()]);
Although it clearly doesn't seem very memory-friendly.