Counting array reference input and displaying count -- infinite loop - java

I am trying to display the occurrence of how many times an integer occurs in an array but I get an infinite loop/logic error. For instance, if the user enters: 2, 5, 6, 5, 4, 3, 23, 43, 2, 0 then it should display:
2 occurs 2 times
3 occurs 1 time
4 occurs 1 time
5 occurs 2 times
6 occurs 1 time
23 occurs 1 time
43 occurs 1 time
Any help would really be appreciated. Note: This is not an assignment or homework, It is a exercise question from intro to Java book by Y.D. Lang
import java.util.*;
public class CountNumbers {
public static void main(String[] args) {
System.out.println("Enter the integers between 1 and 100: ");
int[] arrayRefVar = createList();
int[] countNum = countNumbers(arrayRefVar);
displayCount(countNum, arrayRefVar);
}
public static int[] createList() {
Scanner Input = new Scanner(System.in);
int[] List = new int[100];
int i = 0;
while (List[i] != 0) {
List[i] = Input.nextInt();
i++;
}
return List;
}
public static int[] countNumbers(int[] List) {
int[] count = new int[100];
for (int i = 0; i < count.length; i++) {
count[i] = i;
}
int[] countNum = new int[List.length];
for (int i = 0; i < countNum.length; i++) {
countNum[i] = 0;
}
for (int i = 0; i < List.length; i++) {
for (int j = 0; j < count.length; j++) {
if (List[i] == count[j]) {
countNum[i]++;
}
}
}
return countNum;
}
public static void displayCount(int[] countList, int[] arrayRefVar) {
for (int i = 0; i < arrayRefVar.length; i++) {
System.out.println(arrayRefVar[i] + " occurs " + countList[i] + " " + checkPlural(arrayRefVar[i]));
}
}
public static String checkPlural(int n) {
if (n > 1) {
return "times";
} else {
return "time";
}
}
}

If your input should end in 0, then you should check whether the currently read int is zero or not.
while(i < List.length) {
List[i] = Input.nextInt();
if(List[i] == 0)
break ;
++i;
}
Since you are checking for the condition after incrementing i, you are not checking the current value.
Note : nextInt() method from the Scanner class can throw exceptions namely : InputMismatchException, NoSuchElementException and IllegalStateException. So either handle it in a try catch block or make the caller handle it by throwing the exception.

So I finally got it after countless tries, if anybody has any suggestions to make the code more efficient the input would be greatly appreciated. Here it is:
import java.util.Random;
public class CountSingleDigits {
public static void main (String[] args) {
int[] arrayRefVar = createList();
int[] counts = new int[10];
for (int i = 0; i < 10; i++) {
counts[i] = i;
}
int[] tempCounts = new int[10];
for (int i = 0; i < arrayRefVar.length; i++) {
for (int j = 0; j < 10; j++) {
if (arrayRefVar[i] == counts[j]) {
tempCounts[j]++;
}
}
}
for (int i = 0; i < 10; i++) {
System.out.println(counts[i] + " appears " + tempCounts[i] + " times ");
}
for (int i = 0; i < arrayRefVar.length; i++) {
if (i % 10 == 0) {
System.out.println();
}
System.out.print(arrayRefVar[i] + " ");
}
}
public static int[] createList() {
Random f = new Random();
int[] List = new int[100];
for (int i = 0; i < List.length; i++) {
List[i] = f.nextInt(9);
}
return List;
}
}

One issue is that your while loop for user input is never entered. You use 0 as the sentinel value to exit user input, however, when you initialize an array of integers, they are all 0 by default.
int[] List = new int[100];
int i = 0;
//problem: while loop never entered
while (List[i] != 0) {

Related

Java: Given a number, get the highest sequential occurrences in an Array

I am new to Java Programming (or programming infact).
I have an array which contains either 4 or 6 only. Given a number, either 4 or 6, find the highest sequential occurrence of the given number.
I need highest sequential occurrence count
Example: arr[{4,4,6,6,4,4,4,4,4,6}]
If the above array is given, and next input number is 4, the output should be 5. Because the number 4 has occurred sequentially 5 times.
public static void main(String[] args) throws IOException {
String arrayTK = br.readLine(); // Input is 4466444446
int[] inpArray = new int[10];
for (int i = 0; i < 10; i++) {
inpArray[i] = arrayTK.charAt(i) - '0';
}
int maxSequenceTimes = 0;
for (int j = 0; j < 10; j++) {
// Logic
}}
Any help would be greatly appreciated.
Edit
We will separate and count all sequences and then search in each sequence to know which sequence contain the biggest length.
int[] arr = {4,4,6,6,4,4,4,4,4,6};
boolean newSeq = false;
int diffrentSeq = 0;
int currentNumber;
//Get sequence numbers
for (int i = 0; i < arr.length; i++) {
currentNumber = arr[i];
if (i >= 1 && currentNumber != arr[i - 1])
newSeq = true;
else if (i == 0)
newSeq = true;
//It's new sequence!!
if (newSeq) {
diffrentSeq++;
newSeq = false;
}
}
System.out.println(diffrentSeq);
int[] maxSequencSize = new int[diffrentSeq];
int lastIndex = 0;
for (int i = 0; i < maxSequencSize.length; i++) {
int currentNum = arr[lastIndex];
for (int j = lastIndex; j < arr.length; j++) {
if (arr[j] == currentNum) {
maxSequencSize[i]++;
lastIndex = j + 1;
} else break;
}
}
System.out.println(max(maxSequencSize));
You need to get max value which act the max sequence length:
private static int max(int[] array){
int maxVal = 0;
for (int anArray : array) {
if (anArray > maxVal)
maxVal = anArray;
}
return maxVal;
}
String arrayTK = br.readLine(); // Input is 4466444446
Because your first input is a string, you don't need to convert it to an int array and if you are using you can use:
String arrayTK = "4466444446";
int result = Arrays.asList(arrayTK.replaceAll("(\\d)((?!\\1|$))", "$1;$2").split(";"))
.stream().max(Comparator.comparingInt(String::length)).get().length();
System.out.println(result);
Explanation :
arrayTK.replaceAll("(\\d)((?!\\1|$))", "$1;$2") put a separator between each two different numbers the result should be 44;66;44444;6
.split(";") split with this separator (i used ; in this case) the result is ["44", "66", "44444", "6"]
stream().max(Comparator.comparingInt(String::length)).get() get the max input
.length() to return the length of the result
Ideone demo
Edit
How I modify the same, to get count to any specific number. I mean, max sequential occurrence of number 4
In this case you can just add a filter .filter(t -> t.matches(number + "+")) which mean get only the numbers which match 4+ where 4 can be any number :
...
int number = 6;
int result = Arrays.asList(arrayTK.replaceAll("(\\d)((?!\\1|$))", "$1;$2").split(";"))
.stream()
.filter(t -> t.matches(number + "+"))
.max(Comparator.comparingInt(String::length)).get().length();
You need something like this:
import java.util.Scanner;
public class A {
public static void main(String[] args) {
Scanner br =new Scanner(System.in);
String str = br.next();
int arr[]=new int[str.length()];
for(int i=0;i<str.length();i++)
{
arr[i]=str.charAt(i)-'0';
//System.out.println(arr[i]);
}
int j=0;
int count=1,max=0;
for(int i=0;i<str.length();i++)
{
if(i==0){
j=arr[i];
}
else
{
if(arr[i]==j)
{
count++;
//System.out.println(" "+count);
}
else
{
if(max<count){
max=count;
}
count=1;
j=arr[i];
}
}
}
if(max<count){
max=count;
}
System.out.println(max);
}
}
That should do the work. Every time you find the matching value you start counting and when the streak is over you compare the length with the maximum length you have found so far.
public int logic(int[] inpArray, int num) {
int count = 0, max = 0
for(int i = 0; i < 10; ++i){
if(inpArray[i] == num) {
count++
else{
if(count > max)
max = count;
count = 0;
}
}
if (count > max)
max = count;
return max;
}

Although not exceed index, I get error by the index

My question is
( - Write the following method that merges two sorted lists
into a new sorted list. Write a test program that prompts the user to enter two sorted lists and displays the merged list. Here is a sample run. Note that the first number in the input indicates the number of the elements in the list. - )
When I run this code, Eclipse give error.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at single_dimension_all_arrays.Merge_two_sorted_lists.getNumber(Merge_two_sorted_lists.java:60)
at single_dimension_all_arrays.Merge_two_sorted_lists.main(Merge_two_sorted_lists.java:77)
I can't understand why give the error. I can't exceed index.
private static void sort(int [] list3)
{
int temp=0;
for (int i = 0; i < list3.length; i++)
{
for (int j = 0; j < list3.length; j++)
{
if(list3[i]<list3[j])
{
temp=list3[i];
list3[i]=list3[j];
list3[j]=temp;
}
}
}
for (int i = 0; i < list3.length; i++)
{
System.out.println(list3[i]);
}
}
private static void getNumber(int [] list1,int [] list2)
{
Scanner scan = new Scanner(System.in);
int [] list3 = new int[list1.length+list2.length];
for (int i = 1; i < list1.length; i++)
{
System.out.println("Please, enter the number");
list1[i] = scan.nextInt();
}
for (int i = 1; i < list2.length; i++)
{
System.out.println("Please,enter the number");
list2[i]= scan.nextInt();
}
for (int i = 0; i <= list3.length; i++)
{
if(i<list1.length)
{
list3[i]=list1[i];
}
else if(i>list1.length)
{
list3[i] = list2[i];
}
}
sort(list3);
}
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please,enter the length of list1");
int l1 = scan.nextInt();
System.out.println("Please, enter the length of list2");
int l2 = scan.nextInt();
int [] list1 = new int[l1];
int [] list2 = new int[l2];
list1[0]=l1;
list2[0]=l2;
getNumber(list1,list2);
}
}
Thanks..:)
Although not exceed index...
Yes you do:
for (int i = 0; i <= list3.length; i++)
// ----------------^
The valid range of indexes is 0 to length - 1, so that should be < as it is in several other parts of your code.
Side note: You're also skipping the first element in arrays in a few places:
for (int i = 1; i < list1.length; i++)
// ----------^

Cut the sticks: Hackerrank warmup challenge

I've been trying to solve the warmup challenges on Hackerrank. For this particular challenge - https://www.hackerrank.com/challenges/cut-the-sticks - I've written some code, and although it seems logically correct to me, I'm not getting the right answer.
My Code -
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int lengths[] = new int[n];
List<Integer> output = new LinkedList<Integer>();
for (int i = 0; i < n; i++)
lengths[i] = sc.nextInt();
sc.close();
Arrays.sort(lengths);
for (int i = 0; i < n; i++) {
if (lengths[i] == 0)
continue;
else {
output.add(n - i);
for (int j = i; j < n; j++) { // This loop isn't working like it should
lengths[j] -= lengths[i];
// System.out.print(lengths[j] + " "); // For debugging purposes
}
// System.out.println("");
}
}
for (int i = 0; i < output.size(); i++)
System.out.println(output.get(i));
}
}
For the following input -
6
5 4 4 2 8 2
The output I get is -
6
5
4
3
2
1
The correct output should be -
6
4
2
1
I tried to display the values of the lengths array throughout the runs of the for loop marked in the code (with a comment), and this is what i get for the same inputs as above -
0 2 4 4 5 8
0 4 4 5 8
0 4 5 8
0 5 8
0 8
0
6
5
4
3
2
1
I'm totally stumped as to why this would happen.
The problem is here:
lengths[j] -= lengths[i];
When i == j is true, this changes the value of lengths[i]. You need to save that value first.
final int v = lengths[i];
for (int j = i; j < n; j++) {
lengths[j] -= v;
}
Had solved it sometime back.
Here's a version of answer, using a do while loop
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int size = scan.nextInt();
int sticks [] = new int[size];
for (int i = 0; i < size; i++){
sticks[i] = scan.nextInt();
}
Arrays.sort(sticks);
do {
int count =0;
int leastLength = sticks[0];
for (int j=0; j < sticks.length; j++){
sticks[j] = sticks[j] - leastLength;
count++;
}
System.out.println(count);
List<Integer> resizeArray = new LinkedList<Integer>();
for ( int i=0; i< sticks.length; i++){
if (sticks[i] != 0){
resizeArray.add(sticks[i]);
}
}
int temp[] = new int[resizeArray.size()];
for (int i = 0; i < resizeArray.size(); i ++){
temp[i] = resizeArray.get(i);
}
sticks = temp;
} while (sticks.length > 0);
}
package com.omt.learn.algo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class CutTheSticks2 {
public static void main(String s[]) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
short N = Short.parseShort(br.readLine());
short[] A = new short[N];
N = 0;
for (String str : br.readLine().split(" ")) {
A[N++] = Short.parseShort(str);
}
Arrays.sort(A);
StringBuffer sb = new StringBuffer();
System.out.println(N);
for (int i = 1; i < N; i++) {
if (A[i - 1] != A[i]) {
sb.append((N - i) + "\n");
}
}
// OUTPUT
System.out.print(sb);
}
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for(int arr_i=0; arr_i < n; arr_i++){
arr[arr_i] = in.nextInt();
}
int count = 2;
int min=1000;
for(int arr_i=0;count !=1 ; arr_i++){ // read
count = 0;
for(int arr_j=0; arr_j < n; arr_j++)// find min
{ if(min >arr[arr_j] && arr[arr_j]!=0)
min=arr[arr_j];
}
for(int arr_k=0; arr_k < n; arr_k++)// sub
{
if(arr[arr_k]>=min)
{ count++;
arr[arr_k]= arr[arr_k] - min;
}
}
System.out.println(count);
}
}
}
This is a working solution in JavaScript. Took me a while to realize that the sort() in JavaScript performs a string comparison in alphabetical order.
function sortNumbers(a, b) {
return a - b;
}
function cutSticks(arr){
var smallestStick = 0;
arr = arr.sort(sortNumbers);
while(arr.length > 0) {
console.log(arr.length);
smallestStick = arr[0];
var newArray = [];
arr.forEach(function (val) {
var newValue = val - smallestStick;
if (newValue > 0) {
newArray.push(newValue);
}
});
arr = newArray;
}
}
function main() {
var n = parseInt(readLine());
arr = readLine().split(' ');
arr = arr.map(Number);
cutSticks(arr);
}
Hope it helps!
Java Version. Passed all tests, but not sure if is best performance.
static int[] cutTheSticks(int[] arr) {
List<Integer> sticks = Arrays.stream(arr).boxed().collect(toList());
List<Integer> cuts = new ArrayList<>();
while (true) {
int min = sticks.stream().mapToInt(Integer::valueOf).min().getAsInt();
Iterator it2 = sticks.iterator();
int cuted = 0;
List<Integer> temp = new ArrayList<>();
while (it2.hasNext()) {
int v = (int) it2.next();
if (v == min) {
it2.remove();
cuted++;
} else {
int nv = v - min;
it2.remove();
temp.add(nv);
cuted++;
}
}
cuts.add(cuted);
sticks.addAll(temp);
if (sticks.isEmpty()) {
break;
}
}
return cuts.stream().mapToInt(Integer::valueOf).toArray();
}

How do I sort the numbers inputted from an array to tell how many times the number was entered

Ok so this is my code. I'm supposed to gather 10 numbers of input and then sort them in descending order by the number of which they appear.
Ex. {0,0,1,2,2,2]
My output would be "Mode=2 and then have 2 appears 3 times, 0 appears two times, 1 appears once."
My code can gather the 10 integers and find the mode but I'm having issues trying to sort the numbers in that way. This is what I have so far and I'm stuck.
import java.util.*;
class question2
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int[] arrTwo = new int[10];
int x=0;
for (int i = 0; i < 10; i++)
{
System.out.println("Enter number: " + (i + 1));
arrTwo[i] = scan.nextInt();
}
mode(arrTwo);
int temp;
int bs[] = new int[10];
for ( x=0 ; x<=8 ; ++x )
{
if (bs[x]>bs[x+1])
{
temp=bs[x];
bs[x]=bs[x+1];
bs[x+1]=temp;
x=-1;
}
}
for(int i = 0; i <= bs.length-1; i++)
{
for(int index=0; index <= 99 ; index++)
{
if (i == i)
{
bs[i] +=1;
}
}
System.out.println("The number " + i + " is generated " +arrTwo[i] + " times");
}
}
public static void mode(int[] array)
{
int modeTrack[] = new int[10];
int max =0; int number =0;
for (int i = 0; i < array.length; i++)
{
modeTrack[array[i]] += 1;
}
int maxIndex = 0;
for (int i = 1; i < modeTrack.length; i++)
{
int newNum = modeTrack[i];
if (newNum > modeTrack[maxIndex])
{
maxIndex = i;
}
}System.out.println("The mode is: "+maxIndex);
}
My output isn't listing my numbers, just 0-9 and the generated times is just going from 1-9 with no basis or order.
this code:
int bs[] = new int[10];
for ( x=0 ; x<=8 ; ++x ){
if (bs[x]>bs[x+1]) {
temp=bs[x];
bs[x]=bs[x+1];
bs[x+1]=temp;
x=-1;
}
}
does nothing. On initialization bs is filled with zeroes bs[x-1] is never greater than bs[x] because all values are the same.
also
if (i == i){
is always true

Finding multiple modes in an array of integers with 1000 elements

So I need a way to find the mode(s) in an array of 1000 elements, with each element generated randomly using math.Random() from 0-300.
int[] nums = new int[1000];
for(int counter = 0; counter < nums.length; counter++)
nums[counter] = (int)(Math.random()*300);
int maxKey = 0;
int maxCounts = 0;
sortData(array);
int[] counts = new int[301];
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
This is my current method, and it gives me the most occurring number, but if it turns out that something else occurred the same amount of times, it only outputs one number and ignore the rest.
WE ARE NOT ALLOWED TO USE ARRAYLIST or HASHMAP (teacher forbade it)
Please help me on how I can modify this code to generate an output of array that contains all the modes in the random array.
Thank you guys!
EDIT:
Thanks to you guys, I got it:
private static String calcMode(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
toString(modes);
return "";
}
public static void toString(int[] array)
{
System.out.print("{");
for(int element: array)
{
if(element > 0)
System.out.print(element + " ");
}
System.out.print("}");
}
Look at this, not full tested. But I think it implements what #ajb said:
private static int[] computeModes(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
return modes;
}
This will return an array int[] with the modes. It will contain a lot of 0s, because the result array (modes[]) has to be initialized with the same length of the array passed. Since it is possible that every element appears just one time.
When calling it at the main method:
public static void main(String args[])
{
int[] nums = new int[300];
for (int counter = 0; counter < nums.length; counter++)
nums[counter] = (int) (Math.random() * 300);
int[] modes = computeModes(nums);
for (int i : modes)
if (i != 0) // Discard 0's
System.out.println(i);
}
Your first approach is promising, you can expand it as follows:
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts
// First, we have to determine how many modes there are
int nModes = 0;
for (int i = 0; i < counts.length; i++)
{
// increase nModes if counts[i] == maxCounts
}
// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];
// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
// if this is a mode, set result[modeCounter] = i and increase modeCounter
}
return result;
THIS USES AN ARRAYLIST but I thought I should answer this question anyways so that maybe you can use my thought process and remove the ArrayList usage yourself. That, and this could help another viewer.
Here's something that I came up with. I don't really have an explanation for it, but I might as well share my progress:
Method to take in an int array, and return that array with no duplicates ints:
public static int[] noDups(int[] myArray)
{
// create an Integer list for adding the unique numbers to
List<Integer> list = new ArrayList<Integer>();
list.add(myArray[0]); // first number in array will always be first
// number in list (loop starts at second number)
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is different
if (myArray[i] != myArray[i - 1])
list.add(myArray[i]); // add it to the list
}
int[] returnArr = new int[list.size()]; // create the final return array
int count = 0;
for (int x : list) // for every Integer in the list of unique numbers
{
returnArr[count] = list.get(count); // add the list value to the array
count++; // move to the next element in the list and array
}
return returnArr; // return the ordered, unique array
}
Method to find the mode:
public static String findMode(int[] intSet)
{
Arrays.sort(intSet); // needs to be sorted
int[] noDupSet = noDups(intSet);
int[] modePositions = new int[noDupSet.length];
String modes = "modes: no modes."; boolean isMode = false;
int pos = 0;
for (int i = 0; i < intSet.length-1; i++)
{
if (intSet[i] != intSet[i + 1]) {
modePositions[pos]++;
pos++;
}
else {
modePositions[pos]++;
}
}
modePositions[pos]++;
for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
{
if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
isMode = true;
}
List<Integer> MODES = new ArrayList<Integer>();
int maxModePos = 0;
if (isMode) {
for (int i = 0; i< modePositions.length;i++)
{
if (modePositions[maxModePos] < modePositions[i]) {
maxModePos = i;
}
}
MODES.add(maxModePos);
for (int i = 0; i < modePositions.length;i++)
{
if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
MODES.add(i);
}
// THIS LIMITS THERE TO BE ONLY TWO MODES
// TAKE THIS IF STATEMENT OUT IF YOU WANT MORE
if (MODES.size() > 2) {
modes = "modes: no modes.";
}
else {
modes = "mode(s): ";
for (int m : MODES)
{
modes += noDupSet[m] + ", ";
}
}
}
return modes.substring(0,modes.length() - 2);
}
Testing the methods:
public static void main(String args[])
{
int[] set = {4, 4, 5, 4, 3, 3, 3};
int[] set2 = {4, 4, 5, 4, 3, 3};
System.out.println(findMode(set)); // mode(s): 3, 4
System.out.println(findMode(set2)); // mode(s): 4
}
There is a logic error in the last part of constructing the modes array. The original code reads modes[j++] = array[i];. Instead, it should be modes[j++] = i. In other words, we need to add that number to the modes whose occurrence count is equal to the maximum occurrence count

Categories

Resources