I really don't like asking these kinds of questions and this is probably a duplicate, but i am really stuck on this and because i am new to java (not to programming in general) i can't figure it out.
The problem is as follows: The array names should be sorted, and i came up with the following code:
String[] temp_names = names;
for (int i = 0; i < names.length; i++)
{
for (int j = 0; j < names.length; j++)
{
String biggest = ""+(0);
int biggest_index = 0;
for (int chr = 0; chr < ((biggest.length() < temp_names[j].length()) ? biggest.length() : temp_names[j].length()); chr++)
{
if (biggest.toCharArray()[chr] > temp_names[j].toCharArray()[chr])
{
break;
}
else if (biggest.toCharArray()[chr] < temp_names[j].toCharArray()[chr])
{
biggest = temp_names[j];
biggest_index = j;
break;
}
}
names[i] = biggest;
temp_names[biggest_index] = ""+(255);
}
}
The problem occurs at the last line. I set the value to as high as possible so when sorting it is basically ignored (it will always come last). The problem is that when temp_names[biggest_index] is set to '255', biggest is also set to 255 which in turn sets names[i] to 255. This leaves me with an array full of empty names.
I know this has something to do with that java copys the variable as a reference instead of as a value, but when i try to copy/clone it by using names[i] = new String(biggest) it still has the same result. I've tried many different things and now i've run out of ideas so i hope someone here can help.
Thanks in advance for any answers,
Harm
-Edit:
This is an exercise for school so i can't just use standard java functions.
class SOCLass {
public static void main(String[] args){
String[] names = new String[] {"joe", "bill"};
String[] temp_names = names;// new String[names.length];
//System.arraycopy(names, 0, temp_names, 0, 2);
for (int i = 0; i < names.length; i++)
{
for (int j = 0; j < names.length; j++)
{
String biggest = ""+(0);
int biggest_index = 0;
for (int chr = 0; chr < ((biggest.length() < temp_names[j].length()) ? biggest.length() : temp_names[j].length()); chr++)
{
if (biggest.toCharArray()[chr] > temp_names[j].toCharArray()[chr])
{
break;
}
else if (biggest.toCharArray()[chr] < temp_names[j].toCharArray()[chr])
{
biggest = temp_names[j];
biggest_index = j;
break;
}
}
names[i] = biggest;
temp_names[biggest_index] = ""+(255);
}
}
for(String s : names)
System.out.println(s);
for(String s : temp_names)
System.out.println(s);
}
}
This is the code as you wrote it. It prints out 255 on both. Comment in the new String[...] and System.arraycopy(...) and it prints bill the longest/biggest.
By not allocating a new array, temp_names and names are the same. Changes in one reflect on the other
Related
Im trying to initialise all the elements of the 2d array into a string "EMPTY". but When ever I try to initialise the array it gets null values. I checked errors in the for loop but couldn't see any
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
}
Your loops are nested wrongly, which will result in the filling process not being complete while you're trying to process its results. You need
public static void arr_2d() {
String[][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
Actually for(int b) is in for(int i); that's why you observe null values. If you move for(int b) outside of for(int i), there will be no null values.
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
Check the comments given below in the snippet:
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
// you can have the sysout statement here as well instead of having looping the entire array again.
System.out.print(arr[i][a] + " ");
}
// this loop must be executed separately inorder to check values present in the array or else you can have a sysout statement when assigning the "empty" value in the array.
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
}
Although the answers you have are correct I will add that one problem is your code style is prone to errors.
Your mistake was traversing the array incorrectly. The correct way is traversing the array twice, one of filling and another for printing, but instead it seems you have attempted to do everything in one shot. That mistake can be avoided with a better code style.
This is how I would have written your code in imperative style:
String[][] arr = new String[3][2];
for (String[] a : arr)
Arrays.fill(a, "EMPTY");
for (String[] a : arr)
System.out.println(Arrays.toString(a));
Notice the code is much shorter, so there's less chances of mistakes. It's also a lot more obvious that you're traversing twice.
Instead of traversing an array explicitly:
for (int i = 0; i++; i < arr.length())
Use the implicit for loop:
for (String[] value: arr)
Instead of filling an array explicitly:
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
Use the already provided fill method:
Arrays.fill(value, "EMPTY");
Instead of printing an array explicitly:
for (String string : strings) {
System.out.print(string + " ");
}
System.out.println();
Use the already provided print method:
for (String[] a : arr)
System.out.println(Arrays.toString(a));
However, I would have written in functional style:
String [][] arr = new String[3][2];
Arrays.stream(arr)
.forEach(a -> Arrays.fill(a, "EMPTY"));
Arrays.stream(arr)
.map(Arrays::toString)
.forEach(System.out::println);
One particular advantage is that you are encouraged to think in a more abstract way. Instead of thinking how to explicitly set or print each element of the array, you are encouraged to use methods that implicitly traverse, transform or perform generic computations on all elements of the array.
I know that an ArrayList would do this job much more simple but this is just for arrays so I'm stuck with it.
This is my method so far:
public boolean remove( String name) {
int temp = 0;
for (int i = 0; i<counter; i++) {
if (friends[i].equals(name)) {
friends[i]=null;
for (int j = i; j > counter; j++) {
friends[j] = friends[j+1];
}
return true;
}
}
return false;
}
The result I want is:
String[] friends = {"Sean", "James", "Andrew", "Garfield", "Patrick"};
myfriends.remove("James");
System.out.println(Arrays.toString(friends));
console output: Sean, Andrew, Garfield,Patrick, null
This is where using a debugger would be useful.
I would change j > counter to j < counter and set friends[counter-1] = null; at the end, no point setting friends[i] = null; as the first thing you are going to do is overwrite it.
NOTE: You code assumes there is no duplicates.
This is my code, but I know this is not right. I have written a lot of code for such a simple task.
Sample input is:
welcome
Sample output is:
com
elc
lco
ome
wel
It should print:
your first string is 'com'
and
your last string is 'wel'
Code:
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
int k1 = k;
int j = 0;
int t = str.length();
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
String[] s1 = new String[j];
for (int i = 0 ; i < j; i++) {
s1[i] = s[i];
}
for (int y = 0; y < j; y++) {
for (int z = y + 1; z < j; z++) {
if(s1[z].compareTo(s1[y]) < 0) {
String temp = s1[z];
s1[z] = s1[y];
s1[y] = temp;
}
}
}
System.out.println(s1[0]);
System.out.println(s1[1]);
}
}
Note: I split my strings, but I'm not able to arrange strings in alphabetical order, and feel that I have used a lot of arrays. Is there a better way to do this?
You can
reduce the number of variables,
use collections (list in this case) instead of Arrays to avoid having to set a size (1000)
Sort using the framework
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
List<String> cutStrings = new ArrayList<String>();
for (int i = 0; i < str.length() - k; i++) {
cutStrings.add(str.substring(i, i + k));
}
Collections.sort(cutStrings);
System.out.println(cutStrings.get(0));
System.out.println(cutStrings.get(cutStrings.size()-1));
}
You can easily sort your String[] array by simply using
Arrays.sort(s);
This will sort your strings in the default order. If you need any other kind of order you can pass the comparator as a second parameter.
You can get first and last by getting s[0] and s[s.length-1]
I did a quick implementation of your requirements. It might not be exactly what you're looking for but it should get you started. :)
So, I used an ArrayList to grab the substrings and the use the Collections library to do the sorting for me. This is just one of the many ways of solving the problem, btw. The input word can vary in size so I felt that a list would be appropriate for this situation.
String s = "welcome";
List<String> words = new ArrayList<String>();
for (int i = 0; i < s.length() - 2; i++) {
String chunk = s.charAt(i) + "" + s.charAt(i + 1) + ""
+ s.charAt(i + 2);
words.add(chunk);
System.out.println(chunk);
}
Collections.sort(words);
System.out.println(words.toString());
Feel free to let me know if you have any questions or if I have made a mistake in the code.
Good luck!
Actual problem of your code is splitting. Sorting will work. If j value 1 and k1 value 3 then wel substring is coming. Next loop, (after incrementation of both j and k1 by 1) j value 2 and k1 value 4 then elc substring is coming, etc.
So, instead of
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
use
int k = sc.nextInt();
String [] s = new String [(str.length()/3)+1] ;
for ( int i = 0,a = 0; i<(str.length()-k); i+=k,a++)
{
s[a] = str.substring(i,(i+k));
System.out.println(s[a]);
}
s[s.length-1]=str.substring((str.length()-k),str.length());//to add remaining values
Arrays.sort(s);//sorting alphabatically
for(int i = 0; i < s.length; i++)
System.out.println(s[i]);
}
i value will be incremented by 3. In the for loop (i+=k) where k=3.
Output:
amp
com
e s
ple
wel
my title is bad but I don't have an idea what it should be. My question is simple, I have four arraylist and I want to get similar words from two of them and put another arraylists. Anyway my array lists like;
arrList1 = {car, apple, many, car, tyty, man, superman};
arrList2 = {stack, vs, etc, vs, car, tyty, stack, tyty, many, car, apple};
I tried this;
for (int i = 0; i < arrList1.size(); i++) {
for (int j = 0; j < arrList2.size(); j++) {
if (arrList1.get(i).equals(arrList2.get(j))) {
arrList3.add(arrList1.get(i);
arrList4.add(arrList2.get(j);
}
}
But as you see arrList1 and arrList2 have duplicates so arrList4 will have same element more than normal. Also I have to count elements which are in arrList1 and arrList2 so I shouldn't use Set Collections. What should I do?
Try
ArrayList<String> temp = new ArrayList<String>();
boolean found = false;
for (int i = 0; i < arrList1.size(); i++) {
found = false;
for (int j = 0; j < arrList2.size(); j++) {
if (arrList1.get(i).equals(arrList2.get(j))) {
found = true;
if (!temp.contains(arrList2.get(j)) {
arrList4.add(arrList2.get(j));
}
}
}
if (found) {
arrList3.add(arrList1.get(i));
temp.add(arrList1.get(i));
}
}
This will check if the new ArrayList does not already contain the item.
Try this
ArrayList tempList=new ArrayList(arrList1);
tempList.removeAll(arrList2);
arrList4 = new ArrayList(arrList1);
arrList4.removeAll(tempList);
You should use another type of list but you can also make-do with an arraylist like so:
for (int i = 0; i < arrList1.size(); i++) {
for (int j = 0; j < arrList2.size(); j++) {
if (arrList1.get(i).equals(arrList2.get(j))) {
if(!(arrList3.contains(arrList1.get(i))) {
arrList3.add(arrList1.get(i);
}
if(!(arrList4.contains(arrList2.get(j))) {
arrList4.add(arrList2.get(j);
}
}
}
hope that helps.
I'm coding trough codingbat.com/java and ran into an error i don't understand. I got two String arrays and want to compare them. If I just use the arrays all works fine (but the result is not right). To get the right result I programmed a helper function which eliminates all duplicates of an array. I tested the helper function, it returns the array shortened of the duplicates.
I can retrieve the values in the new Arrays with _a[i] etc., and don't get errors, but if i use _a[0].equals(_b[0]) or _a[0].compareTo(_b[0]) I get a NullPointerException (_a[0] == _b[0] works fine...).
If I just use the original arrays a,b the code runs without problems. I don't comprehend why i get a NullpointerException there.
Thanks for any help!
Code:
public int commonTwo(String[] a, String[] b) {
String[] _a = killDuplicate(a);
String[] _b = killDuplicate(b);
int ai=0, bi=0,count=0;
for (int i = 0; ai < _a.length & bi < _b.length; i++){
if ( _a[ai].compareTo(_b[bi]) > 0) { //NullPointerException here, but not if I use a,b
bi++;
} else if ( _a[ai].compareTo(_b[bi]) < 0){ //NullPointerException here, but not if I use a,b
ai++;
} else {
count++;
ai++;
bi++;
}
}
return count;
}
Helper Function:
public String[] killDuplicate(String[] a){
String temp = "";
int counter = 0, counter2 = 0;
for (int i = 0; i < a.length; i++){
if (! a[i].equals(temp)){
temp = a[i];
} else {
a[i] = "";
counter++;
}
}
String[] result = new String[a.length - counter];
for (int i = 0; counter2 < counter; i++){
if (a[i].equals("")) {
counter2++;
}
} else {
result[i-counter2] = a[i];
}
return result;
}
I guess you assume that your array of strings is sorted, otherwise your killDuplicate method wouldn't make sense at all.
The problem with your code is that in the second for loop in killDuplicate method you iterate with condition counter2 < counter which says iterate until all found duplicates are passed. So when you find your last duplicate you exit without filling the rest of the array. Try with example: new String[]{"A", "A", "B", "C"} you'll get [A, null, null].
There are numerous things that can be improved but the simplest modification of your code below. (I've changed only the second for loop)
public String[] killDuplicate(String[] a) {
String temp = "";
int counter = 0, counter2 = 0;
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(temp))
temp = a[i];
else {
a[i] = "";
counter++;
}
}
String[] result = new String[a.length - counter];
for (int i = 0; i < a.length; i++) {
if (a[i].equals("")) continue;
result[counter2] = a[i];
counter2++;
}
return result;
}