I'm doing a beginner Java tutorial on Lists, and am presented with the below problem
// 1) Declare am ArrayList of strings
// 2) Call the add method and add 10 random strings
// 3) Iterate through all the elements in the ArrayList
// 4) Remove the first and last element of the ArrayList
// 5) Iterate through all the elements in the ArrayList, again.
Below is my code
import java.util.ArrayList;
import java.util.Random;
public class Ex1_BasicArrayList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i <= 10; i++){
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
sb.append(alphabet.charAt(rand.nextInt(alphabet.length())));
String randy = sb.toString();
list.add(randy);
}
for (int i = 0; i < list.size(); i++){
System.out.print(list.get(i));
}
list.remove(0);
list.remove(list.size()-1);
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
}
I have managed to generate an output, but it is incorrect :(
For my first System.out.print(list.get(i)); I'm trying to get an output for 10 String values, but I get 12.
Sample output: nhgacqhlejph
And when I run the second System.out.println(list.get(i));, I get an output for 8 String Values, which is correct if I started out with 10 in the list, but I have 12, so it means that 4 values were removed :/
Sample output:
g
a
c
q
h
l
e
j
Does anyone know where I went wrong with my code?
To repeat:
I wish to get 10 String values of one letter each from the first System.out.print(list.get(i));
I also want to get 2 less String values from the original list by running the second System.out.println(list.get(i));
First, the for loop should stop at i=9 not at i=10. Hence the loop should be as follows:
for (int i = 0; i < 10; i++){
Second, when printing the list after removing the first and last elements, you're not printing a new line to distinguish between the two outputs. You can add a println between them so that they are separated:
for (int i = 0; i < list.size(); i++){
System.out.print(list.get(i));
}
System.out.println();
list.remove(0);
list.remove(list.size()-1);
Having said this, your implementation is not very efficient in that it creates a StringBuilder in every iteration of the loop as well as a Random object. You can create only one Random object to use it for every iteration. You also don't need a StringBuilder to begin with. The program can be simplified to the following, for example:
ArrayList<String> list = new ArrayList<String>();
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 10; i++){
list.add(String.valueOf(alphabet.charAt(rand.nextInt(alphabet.length()))));
}
First of all: int i = 0; i <= 10; i++ generates 11 chars.
First loop will produce 11 characters (without newline).
Second loop will produce 9 characters (with newlines).
Therefore you see 12 characters (11 from 1st loop + one from the 2nd) in one line and then 8 characters on next lines
for (int i = 0; i <= 10; i++)
Above for lop runs from 0 till 10 both including (so it runs for 11 times) apart from this your code looks fine. change i<=10 to i<10
I had rewritten the program and you could use this for your testing
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Ex1_BasicArrayList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 10; i++){
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
sb.append(alphabet.charAt(rand.nextInt(alphabet.length())));
String randy = sb.toString();
list.add(randy);
}
printList(list);
// Remove Elements
list.remove(0);
list.remove(list.size()-1);
printList(list);
}
/**
* #param list
*/
private static void printList(List<String> list) {
System.out.println("List size:"+list.size());
System.out.println("List="+list);
for(String listElement: list){
System.out.println(listElement);
}
}
}
Output of the program is
List size:10
List=[k, g, i, a, g, k, s, s, x, t]
k
g
i
a
g
k
s
s
x
t
List size:8
List=[g, i, a, g, k, s, s, x]
g
i
a
g
k
s
s
x
Note
List entries would vary as they are picked randomly, but size would be 10 & 8 before delete & after delete respectively
Related
I am pretty new in this world, and I must say sometimes things that looks easy are pretty harsh.
I am stuck with a task that entails dealing with an array and for-loops.
I should iterate over the array and for every iteration step print a different random string. My current code is not working correctly, the only thing I'm getting a random item and the same index printed multiple times.
My output right now:
relax
2
2
2
2
How can I fix that and get a correct randomized output?
My code:
public static void main(String[] args) {
int i;
String Cofee[] = {"pick it","drink it","relax","put it in a cup",};
java.util.Random randomGenerator = new java.util.Random();
int x = Cofee.length;
int y = randomGenerator.nextInt(x);
String frase = Cofee[y] ;
System.out.println(frase);
for(i = 0; i < Cofee.length; i++)
System.out.println(y);
}
You assign a value to y once, and you print y repeatedly. The value of y doesn't change. To do that, you would need to call randomGenerator.nextInt(x) for each iteration of the loop!
However, if you want to randomize and print the array, use:
public static void main(String[] args)
{
String[] coffee = {"pick it","drink it","relax","put it in a cup",};
// this wraps the array,
// so modifications to the list are also applied to the array
List<String> coffeeList = Arrays.asList(coffee);
Collections.shuffle(coffeeList);
for(String value : coffee)
System.out.println(value);
}
As an aside, don't use String coffee[], but use String[] coffee. Although Java allows putting the array type after the variable name, it is considered bad form.
Or use a list directly:
public static void main(String[] args)
{
List<String> coffeeList = Arrays.asList("pick it","drink it","relax","put it in a cup");
Collections.shuffle(coffeeList);
for(String value : coffeeList)
System.out.println(value);
}
For that, you can implement a shuffling algorithm.
It's not so scaring as it might sound at first. One of the famous classic shuffling algorithms, Fisher–Yates shuffle is relatively easy to grasp.
The core idea: iterate over the given array from 0 to the very last index, and for each index swap the element that corresponds to the randomly generated index between 0 and the current index (i) with the element under the current index.
Also, I would advise creating a separate array representing indices and shuffle it in order to preserve the array of string its initial state (you can omit this part and change the code accordingly if you don't need this).
That's how it might be implemented:
public static final Random RANDOM = new Random(); // we need an instance for random to generate indices
A Fisher–Yates shuffle implementation:
public static void shuffle(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int j = RANDOM.nextInt(i + 1); // generating index in range [0, i]
swap(arr, i, j); // swapping elements `i` and `j`
}
}
Helper-method for swapping elements:
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
Usage-example:
String[] coffee = {"pick it","drink it","relax","put it in a cup"};
int[] indices = new int[coffee.length];
for (int i = 0; i < indices.length; i++) indices[i] = i; // or Arrays.setAll(indices, i -> i); if you're compfortable with lambda expressions
shuffle(indices);
for (int i = 0; i < coffee.length; i++) {
String next = coffee[indices[i]];
System.out.println(next);
}
Output:
drink it
pick it
put it in a cup
relax
I am trying to sort a string 2d array taken as user input. But this code is working for some cases and not working for some.
The code is:
public class Source {
public static void main(String args[]) throws Exception {
Scanner sc = new Scanner(System.in);
String[][] customerDetails= new String[5][3];
customerDetails[0][0]="10";
customerDetails[0][1]="Raj";
customerDetails[0][2]="Chennai";
customerDetails[1][0]="100";
customerDetails[1][1]="Akshay";
customerDetails[1][0]="Pune";
customerDetails[2][0]="20";
customerDetails[2][1]="Simrath";
customerDetails[2][2]="Amristar";
customerDetails[3][0]="30";
customerDetails[3][1]="Gaurav";
customerDetails[3][2]="Delhi";
customerDetails[4][0]="101";
customerDetails[4][1]="Ganesh";
customerDetails[4][2]="Chennai";
/*for (int i = 0; i < 5; i++) {
for (int j = 0; j < 3; j++) {
//customerArray[i][j] = sc.nextLine();
}
}*/
Arrays.sort(customerArray, (a, b)->a[0].compareTo(b[0]));
for (int y = 0; y < 5; y++) {
for (int z = 0; z < 3; z++) {
System.out.println(customerArray[y][z]);
}
}
}
}
I have given direct inputs in this code. I want to sort the numbers as String
You are getting wrong answer because you were comparing 0th index of each row of 2D array which are String. So, according to string comparison logic the outputs are correct. To get the sorting order as integer, you have to convert 0th index of each row to Integer in your comparator.
Modify your sort method call like below which should work according to your expectation because a[0] and b[0] are converted to Integer before comparison:
Arrays.sort(customerArray, (a, b)->Integer.valueOf(a[0]).compareTo(Integer.valueOf(b[0])));
Output:
10
Akhil
Pune
20
Rajni
Hyderabad
30
Praveen
Delhi
100
Rohith
Chennai
101
Sam
Bangalore
I have this array
int [] marc = new int[4];
i need to insert a set of non repeating random numbers in the range of 1-10 to it
i'm using this for loop to set random numbers
for (he = 0; he < 4; he++) {
marc[he] = rn.nextInt(10 - 1 + 1) + 1;
marc[he]++;
}
it gives me random numbers but repeated ones inside the array
i'm also using
java.util.Random;
Well, yes, numbers can be repeated while being random. You need to do your own logic to validate if they're already on the array, this can be done with the following code:
In the code I used an array of 10 elements to observe there aren't repeated numbers even on that situation.
import java.util.Random;
public class RandomNumbersNoRepeating {
public static void main(String[] args) {
int array[] = new int[10];
Random random = new Random();
//Fills the array
for (int i = 0; i < array.length; i++) {
boolean found = false;
int r = 0;
do {
found = false;
r = random.nextInt(10) + 1;
//Here we check if the number is not on the array yet
for (int j = 0; j < array.length; j++) {
if (array[j] == r) {
found = true;
break;
}
}
} while (found);
array[i] = r;
}
//Prints the array
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Another possible solution, as given in a comment could be to shuffle an array from 1-10, and get the first four numbers
Using java.util.Random; will generate repetitive numbers more often when your range is small, which in your case is only 10. There is no condition in your code that checks whether the generated random number already exists in your array or not.
Before inserting a generated number in to the array, you first need to check whether that number already exists in your array. If it does not, you insert that number in the array, otherwise you generate a next random number.
I know from reading other questions on the forumn that Array indexing is causing the problem, but I don't know any way around it. I commented where the throw happens. The whole throw is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
at assignment4.AnagramTester.main(AnagramTester.java:36)
If anyone has any ideas how I can make this work, let me know. Also, I don't think any more of my methods are relevant in solving this but I can put them here if needed.
/*areAnagrams
* parameters: sorted strings x & y
* returns boolean
* implements sort method
*/
public static boolean areAnagrams(String x, String y)
{
if(sort(x).equals(sort(y)))
return true;
return false;
}
/*
* This function takes a string array and finds the largest anagram group.
* AnagramComparator.insertionSort() sorts the array by placing anagrams together,
* so no sorting is needed.
* I use ArrayList because I want to be able to freely add to the string array.
* returns a new String[]
*/
public static String[] getLargestAnagramGroup(String[] input)
{
String[] s=input;
AnagramComparator.insertionSort(s, new AnagramComparator());
int largestCount = 0, tempCount=1;
ArrayList<String> largest= new ArrayList<String>();
ArrayList<String> temp= new ArrayList<String>();
for(int i=0; i<s.length; i++)
{
//since it's already sorted, we need only to compare.
//add
temp.add(s[i]);
//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
if (areAnagrams(s[i],s[i+1])) //at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
{
//add s[i+1] to array list
temp.add(s[i+1]);
tempCount++;
}
else
{
//if tempcount> largestcount, empty contents of largest and make temp largest
if (tempCount>largestCount)
{
if(!largest.isEmpty())
largest.clear();
largest=temp;
largestCount=tempCount;
}
//reset tempcount
tempCount=1;
}
}
String[] result= new String[largest.size()];
for (int j=0;j<largest.size();j++)
result[j]=largest.get(j);
return result;
}
your problem is here:
areAnagrams(s[i],s[i+1])
this will fail when i = s.length - 1 because of i + 1 (when i = s.length it is out of bounds, as length returns the number of elements, yet array index starts at 0)
change
for(int i=0; i<s.length; i++)
to
for(int i=0; i<s.length - 1; i++)
Try changing this line:
for(int i=0; i<s.length; i++)
to this:
for(int i=0; i<s.length-1; i++)
You have a loop
for(int i=0; i<s.length; i++) {...
which means that for the maximum allowable value of i, s[i] will be the last element in s.
But within the loop you are referencing s[i + 1], which is past the end of s.
I have tried the below program and i am stuck please assist me.Below is my program
import java.util.ArrayList;
public class PrintNosandRepetition
{
public static void main(String[] args)
{
int a[] = new int[] {1,3,4,5,6,3,2,4,6,7,9,4,12,3,4,6,8,9,7,6,43,2,4,7,7,5,2,1,3,4,6,311,1};
for (int i=0; i< a.length; i++){
System.out.print(a[i]+ " ");
}
for (i=1, j<a.length; j++)
}
The output has to be is the fashion "1- repeated 3 times".etc
You can sort the original array and then loop through it to scan the elements one by one. This will run in O(nlogn).
Or you can use a Map<Integer, Integer> which will store for each number it's number of occurences. This solutions runs in O(n) but uses extra memory.
int a[] = new int[] {1,3,4,5,6,3,2,4,6,7,9,4,12,3,4,6,8,9,7,6,43,2,4,7,7,5,2,1,3,4,6,311,1};
HashMap occurrenceMap = new HashMap()<Integer, Integer>;
int number;
Integer occurrences; //accepts null
for (int i=0; i<a.length; i++){
number = a[i];
occurrences = occurrenceMap.get(number);
if (occurrences == null) { //had no occurrences until this point
occurrenceMap.put(number, 1);
}
else {
occurrenceMap.put(number, occurrences+1);
}
}
//iterate over your map and print the pairs
Can't test it right now so I apologize for any eventual syntax errors.