Beginning Java - Creating a successful binary search algorithm - java

Design an application that has an array of at least 20 integers. It should call a module that uses the sequential search algorithm to locate one of the values. The module should keep a count of the number of comparisons it makes until it finds the value. Then the program should call another module that uses the binary search algorithm to locate the same value. It should also keep a count of the number of comparisons it makes. Display these values on the screen.
I already have the sequential search working properly, and it displays the number of iterations it took to find the desired value. However, I am having trouble with my binary search module. Every time it searches for a value, it always returns the value 1. Here is the code I have excluding the sequential search module.
Appreciate any help.
//Scanner class
import java.util.Scanner;
public class JavaProgramCh9Ex7_test {
//global scanner to read input
static Scanner keyboard = new Scanner(System.in);
//size of array
final static int SIZE = 20;
//main
public static void main(String[] args) {
//populate the array
int [] twentyNumbers = new int [SIZE];
populateTwentyNumbersArray(twentyNumbers);
//sort the numbers using bubble sorting:
bubbleSort(twentyNumbers);
displayTwentyNumbersSorted(twentyNumbers);
//ask the user for a value to search for:
int desiredValue = getValidInteger("Search for a number", 1, 20);
//start the binary search algorithm:
int binSearchComparison = performBinarySearch (twentyNumbers, desiredValue);
System.out.println(binSearchComparison);
}
//Display the 20 integers in the array in ascending-order:
public static void displayTwentyNumbersSorted (int [] numArray){
System.out.println("");
System.out.println("Here are the 20 numbers sorted in ascending-order");
for (int i = 0; i < numArray.length; i++) {
if(i < 19){
System.err.print(numArray[i] + ", ");
}
else{
System.err.print(numArray[i]);
}
}
}
//Perform the binary search for the user's desired value:
public static int performBinarySearch (int [] numArray, int userValue){
int first = 0;
int middle;
int last = (numArray.length - 1);
int iteration = -1;
boolean found = false;
for (int i = 0; i < numArray.length; i++) {
while ((!found) && (first <= last)) {
middle = ((first + last) / 2);
if (numArray [middle] == userValue) {
found = true;
iteration = (i + 1);
}
if(numArray [middle] > userValue) {
last = (middle - 1);
}
if(numArray [middle] < userValue) {
first = (middle + 1);
}
}
}
return iteration;
}
//Populate the array with 20 random integers:
public static void populateTwentyNumbersArray (int [] numArray){
int number = 0;
for (int i = 0; i < numArray.length; i++) {
do{
number = getRandomNumber(1, 20);
}while (checkNum(numArray, number));
numArray[i] = number;
}
}
//Check to make sure the number is unique:
public static boolean checkNum (int [] numArray, int num) {
boolean value = false;
for (int i = 0; i < numArray.length; i++) {
if (numArray[i] == num) {
value = true;
}
}
return value;
}
//Sort the array in ascending order
public static void bubbleSort(int [] numArray){
int temp;
int maxElement;
for(maxElement = (SIZE - 1); maxElement > 0; maxElement--){
for(int i = 0; i <= (maxElement - 1); i++){
if(numArray[i] > numArray[i + 1]){
temp = numArray[i];
numArray[i] = numArray[i + 1];
numArray[i + 1] = temp;
}
}
}
}
//Get a valid Integer from the user to determine the number of seats sold per section:
public static int getValidInteger(String msg, int low, int high) {
int newValue = getInteger(msg);
//Check that the user entered a valid number within the range:
while (newValue < low || newValue > high) {
System.err.println("Please enter a number from " + low + " to " + high + ".");
newValue = getInteger(msg);
}
return newValue;
}
//Check for a valid Integer input from the user:
public static int getInteger(String msg) {
System.out.println(msg);
while (!keyboard.hasNextInt()) {
keyboard.nextLine();
System.err.println("Invalid integer. Please try again.");
}
int number = keyboard.nextInt();
keyboard.nextLine(); //flushes the buffer
return number;
}
//Get a random number to represent the computer's choice:
public static int getRandomNumber(int low, int high){
return (int)(Math.random() * ((high + 1) - low)) + low;
}
}

In your performBinarySearch you check for the all values of array, this maximizes the binary search complexity, though the loop hasn't any effect on searching. If the value present in the array, then the searching function checks whether it is present or not when i=0 and make found=true. After that the inner while loop don't executes as found=true all the times.
For that reason, iterator=(i+1) for i=0 all the times if the value is present in the array, otherwise iterator=-1.
Consider the below performBinarySearch function :
public static int performBinarySearch(int[] numArray, int userValue) {
int first = 0;
int middle;
int last = (numArray.length - 1);
int iteration = 0;
boolean found = false;
while ((!found) && (first <= last)) {
iteration++;
middle = ((first + last) / 2);
if (numArray[middle] == userValue) {
found = true;
break;
}
if (numArray[middle] > userValue) {
last = (middle - 1);
}
if (numArray[middle] < userValue) {
first = (middle + 1);
}
}
if (found) return iteration;
else return -1;
}
Here, I have reused your code with a simple modification. I have deleted your redundant outer loop and calculated the number of iteration each time the while loop executes. If found then make found=true and break the loop(as I have already found the expected value) and return the value.

Related

Incorrect binary search output

I'm having trouble with this binary search on an array. It runs but I get the incorrect output each time. I'm not too sure why. If anybody can help it would be greatly appreciated.
public class chapter7Assignment {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] numbers = {1, 566, 18, 1, 8, 5, 18, 4, 3, 8};
int searchValue;
int foundValue;
System.out.print("Enter a value: ");
searchValue = scanner.nextInt();
foundValue = searchMethod(numbers, searchValue);
if (value == -1) {
System.out.println("Didn't find the value.");
} else {
System.out.println("found the value.");
}
}
// Here's the search method used to pass the array and the scanner
// input into it
public static int thisMethod(int[] array, int value) {
int middle;
int first = 0;
int last = array.length - 1;
int position = -1;
boolean found = false;
while (!found && first < = last) {
middle = (first + last) / 2;
if (array[middle] == value) {
found = true;
position = middle;
} else if (array[middle] > value) {
last = middle - 1;
} else {
first = middle + 1;
}
}
return position;
}
}
As we know, for binary search implementation we need a sorted array. So you need to sort your array first by using following code snippet
private static void sortArray(int[] array){
int temp;
for (int i = 1; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j] < array [j - 1]) {
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
Call this method before calling binary search method as below
sortArray(numbers);
foundValue = searchMethod(numbers,searchValue );
You will have the exact answer.
Happy Coding :)
As people mentioned, you need to sort it first. This code should work, don't forget the import statement at the top.
import java.util.Arrays;
public class chapter7Assignment{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int[] numbers = {1,566,18,1,8,5,18,4,3,8};
int searchValue;
int foundValue;
System.out.print("Enter a value: ");
searchValue = scanner.nextInt();
// Sort in ascending order
Arrays.sort(numbers);
foundValue = searchMethod(numbers,searchValue );
if(value == -1){
System.out.println("Didn't find the value.");
}else{
System.out.println("found the value.");
}
}
// Here's the search method used to pass the array and the scanner
// input into it
public static int thisMethod (int [] array, int value){
int middle;
int first= 0;
int last = array.length -1;
int position = -1;
boolean found = false;
while(!found && first <= last){
middle = (first + last) / 2;
if(array[middle] == value){
found = true;
position = middle;
}
else if(array[middle] > value){
last = middle -1;
}else{
first = middle + 1;
}
}
return position;
}
}
}

Find the median of n values given by the user without using arrays or any function that uses arrays or any other collection

Only manual algorithms on variables are allowed. Collections like list, arrays etc. aren't to be used. (I Used .length() function in the program but it can be manually done by putting a space after every input and counting the number of chars till a space is found)
The problem that using arrays would solve is to store any number of values that the user inputs. This can be solved by storing the values in a string. Since we'd have to know how many characters to pick from the string to form a number, I've also stored the lengths of the numbers in a separate string(Length would generally be of only 1 digit so we'd know for sure that the length of nth number would be at the nth char in the lengthstorage string.)
The algorithm:
Take a number from the string and subtract it from every other number in the string.
If the result is positive, add 1 to the int 'pos'; if negative, to 'neg'; if zero, to 'copy'.
If odd number of numbers are inputed, then the number for which pos + copy >= n/2 and neg + copy >= n/2 is the median.
If even number of numbers are inputed, then we'd have 2 middle numbers fmedian and smedian whose average would be the median. (Refer the code for algorithm).
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input,inputstorage,lengthstorage,inputlength;
int nonrep=0;
System.out.println("Enter the number of values");
int n = sc.nextInt();
int fmedian=0,smedian=0;
System.out.println("Enter a value");
input= sc.next(); //String
inputlength = "" + (char)(input.length()+48);
inputstorage = input;
lengthstorage = inputlength;
for (int i=1; i<n; i++)
{
System.out.println("Enter a value");
input = sc.next();
inputstorage = inputstorage + input;
lengthstorage = lengthstorage + (char)(input.length()+48);
}
int mainnumpos = 0;
for(int j=0;j<n;j++)
{
int copy=0;
int mainnumlength = lengthstorage.charAt(j) - 48;
int neg=0,pos=0;
int mainnum = 0; int factor = 1;int mainnumsign = 0;
for (int m =mainnumlength-1; m >= 0; m--)
{
if(inputstorage.charAt(mainnumpos+m)=='-')
{
mainnumsign = 1;
}
else
{
mainnum += (inputstorage.charAt(mainnumpos+m) - '0') * factor;
factor *= 10;
}
}
mainnumpos = mainnumpos + mainnumlength;
if(mainnumsign==1)
{
mainnum = -mainnum;
}
int position = 0;
for (int q=0;q<n;q++)
{ int fnumsign = 0;
int fnumlength = lengthstorage.charAt(q) - 48;
int fnum = 0;
factor = 1;
for (int l =fnumlength-1; l >= 0; l--)
{
if(inputstorage.charAt(position+l)=='-')
{
fnumsign = 1;
}
else{
fnum += (inputstorage.charAt(position+l) - '0') * factor;
factor *= 10;
}
}
if(fnumsign==1)
{
fnum = -fnum;
}
if((mainnum-fnum)>0)
{
pos++;
}
else if((mainnum-fnum)<0)
{
neg++;
}
else{
copy++;
}
position = position + fnumlength;
}
if((n%2)!=0){
if((double)(pos+copy)>=((double)n)/2.0 && (double)(neg+copy)>=((double)n)/2.0)
{
if(nonrep==0)
{
System.out.println("The median is: "+ mainnum);
nonrep++;
}
}
}
else
{
if ((double)(pos+copy)==(double)n/2.0)
{
fmedian=mainnum;
}
else if((double)(neg+copy)==(double)n/2.0)
{
smedian = mainnum;
}
else if((double)(pos+copy)>=(double)n/2.0 && (double)(neg+copy)>=(double)n/2.0 )
{
fmedian = mainnum;
smedian = mainnum;
}
if(j==n-1){
double evenmedian = ((double)(smedian + fmedian))/2.0;
System.out.println("The median is: "+evenmedian);
}
}
}
}
}

Largest palindrome product

I've written a program to calculate largest palindrome product of 2 three digit number. I've solved this problem at Project Euler, but solving the same in HackerRank fails some test cases. I wonder what's wrong.
Input :
First line contains T that denotes the number of test cases. This is followed by T lines, each containing an integer, N.
Constraints:
1≤T≤100
101101<N<1000000
public class Solution {
static boolean isPalin ( int i){
int low = 0;
String a = String.valueOf(i);
int high = a.length() - 1;
while(low<high){
if(a.charAt(low) == a.charAt(high)){
low++;
high--;
}else{
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int noOfCases = in.nextInt();
int currMax = 0, result = 0;
int no_one, no_two;
int largest = -1;
for(int i=0; i<noOfCases; i++){
currMax = in.nextInt();
for(no_one = 100; no_one<=999; no_one++){
for(no_two = 101; no_two<=999; no_two++){
result = no_one * no_two;
if(isPalin(result)){
if(result > largest && result < currMax )
largest = result;
}
}
}
System.out.println(largest);
}
}
You are testing multiple cases, but only reset largest to -1 at the very start of the program.
Try adding largest=-1; to the start of the loop over i.

(Java) Statistical analysis assignment

I'm currently working on a program designed to perform some statistical analysis. Specifically, I want it to store some random integers (say 10, between min and max inclusive) in an array, compute the min, max, mode, and a few other values through separate methods, and give the user a menu with which to either choose a method (and loop back to the menu, if they do so) or exit.
My biggest problems right now are that the main program requires two inputs to carry out any method (doesn't do anything after putting in the first), and also that each method returns 0 or 0.0.
Here is my code:
import java.util.Random;
public class Stats extends Main
{
int sampleSize;
double count;
double ave;
double sum;
int min;
int max;
int mode;
int evenCount;
int oddCount;
int countMatching;
//Constructor: use an RNG to generate sampleSize integers between minValue and maxValue. Store the numbers in an array named 'data'.
public Stats()
{
sampleSize = 10;
data = new int[sampleSize];
for (int i = 0; i < sampleSize; i++)
{
Random rand = new Random();
data[i] = rand.nextInt((max - min + 1) + min);
}
return;
}
//Method: return the sample set's max value
public int getMax()
{
max = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] > max)
max = data[i];
}
return max;
}
//Method: return the min value
public int getMin()
{
min = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] < min)
min = data[i];
}
return min;
}
//Method: return the average value
public double getAve()
{
count = sampleSize;
sum = 0;
for(int i = 0; i < sampleSize; i++)
{
sum = sum + data[i];
}
ave = sum / count;
return ave;
}
//Method: return the mode; in case of a tie, choose the smallest value
public int getMode()
{
int popularity1 = 0;
int popularity2 = 0;
int array_item;
for(int i = 0; i < sampleSize; i++)
{
array_item = data[i];
for(int j = 0; j < sampleSize; j++)
{
if(array_item == data[j])
popularity1++;
}
if(popularity1 >= popularity2)
{
mode = array_item;
popularity2 = popularity1;
}
}
return mode;
}
//Method: return the count of even numbers
public int getEven()
{
int evenCount = 0;
for (int i = 0; i < sampleSize; i++)
{
if (data[i] % 2 == 0)
evenCount++;
}
return evenCount;
}
//Method: return the count of odd numbers
public int getOdd()
{
int oddCount = 0;
for (int i = 0; i < sampleSize; i++)
{
if (data[i] % 2 != 0)
oddCount++;
}
return oddCount;
}
//Display all numbers, formatted in columns (hint: pg. 158)
public void displaySampleSet()
{
for (int i = 0; i < sampleSize; i++)
{
}
}
//Return the count of numbers in the sample set that match the input parameter
public int countMatching(int match)
{
int countMatching = 0;
return match;
}
//Create a list of private variable(s) that belong to the Stats class
private int[] data;
}
And here is the main program:
import java.util.*;
public class Main
{
public static void main(String[] args)
{
int input;
int stats;
Scanner keyboard = new Scanner(System.in);
Stats g = new Stats();
System.out.println("Welcome to the Stats Program!");
System.out.println();
System.out.println("Main Menu");
System.out.println();
System.out.println("1) Get max value");
System.out.println("2) Get min value");
System.out.println("3) Get the mean");
System.out.println("4) Get the mode");
System.out.println("5) Get the count of even numbers");
System.out.println("6) Get the count of odd numbers");
System.out.println("7) Display the sample set");
System.out.println("8) Return the count of numbers in the sample set that match the input parameter");
System.out.println("9) Exit");
System.out.println();
stats = keyboard.nextInt();
while (stats != 9)
{
if (stats == 1)
{
g.getMax();
input=keyboard.nextInt();
System.out.println("Max is: " + g.getMax());
}
else if (stats == 2)
{
g.getMin();
input=keyboard.nextInt();
System.out.println("Min is: " + g.getMin());
}
else if (stats == 3)
{
g.getAve();
input=keyboard.nextInt();
System.out.println("Mean is: " + g.getAve());
}
else if (stats == 4)
{
g.getMode();
input=keyboard.nextInt();
System.out.println("Mode is: " +g.getMode());
}
else if (stats == 5)
{
g.getEven();
}
else if (stats == 6)
{
g.getOdd();
}
else if (stats == 7)
{
g.displaySampleSet();
}
else if (stats == 8)
System.out.println("");
System.out.println("View other stats?");
System.out.println("");
System.out.println("1) Max 2) Min 3) Mean 4) Mode 5) Count of evens 6) Count of odds 7) Sample set numbers 8) Count of numbers that match input parameter 9) Exit");
stats = keyboard.nextInt();
}
System.out.println("Thank you for using the Stats Program. See you next time!");
}
}
Both programs are incomplete, but I'm still getting values for each method (after two inputs), loops after they execute, and the exit works as intended.
Any tips or parts that are glaringly wrong/missing? I'd really like to understand this.
Thanks in advance!
When you create a Stats, the data array is immediately initialised in the constructor using the max and min fields. But these are zero at this point (because you leave them blank, and Java initialises blank int declarations to zero). You then call your random number generator:
data[i] = rand.nextInt((max - min + 1) + min);
min and max are zero, so this evaluates to:
data[i] = rand.nextInt(1);
and Random.nextInt() returns values up to, but not including, the input (see the docs).
So your 'random' data will always be zeros; therefore the minimum, maximum and average will also be zero.

Count of most occurring digit... Find the digit that occurs most in a given number

the following s the code to
Find the number of occurrences of a given digit in a number.wat shall i do in order to Find the digit that occurs most in a given number.(should i create array and save those values and then compare)
can anyone please help me ..
import java.util.*;
public class NumOccurenceDigit
{
public static void main(String[] args)
{
Scanner s= new Scanner(System.in);
System.out.println("Enter a Valid Digit.(contaioning only numerals)");
int number = s.nextInt();
String numberStr = Integer.toString(number);
int numLength = numberStr.length();
System.out.println("Enter numer to find its occurence");
int noToFindOccurance = s.nextInt();
String noToFindOccuranceStr = Integer.toString(noToFindOccurance);
char noToFindOccuranceChar=noToFindOccuranceStr.charAt(0);
int count = 0;
char firstChar = 0;
int i = numLength-1;
recFunNumOccurenceDigit(firstChar,count,i,noToFindOccuranceChar,numberStr);
}
static void recFunNumOccurenceDigit(char firstChar,int count,int i,char noToFindOccuranceChar,String numberStr)
{
if(i >= 0)
{
firstChar = numberStr.charAt(i);
if(firstChar == noToFindOccuranceChar)
//if(a.compareTo(noToFindOccuranceStr) == 0)
{
count++;
}
i--;
recFunNumOccurenceDigit(firstChar,count,i,noToFindOccuranceChar,numberStr);
}
else
{
System.out.println("The number of occurance of the "+noToFindOccuranceChar+" is :"+count);
System.exit(0);
}
}
}
/*
* Enter a Valid Digit.(contaioning only numerals)
456456
Enter numer to find its occurence
4
The number of occurance of the 4 is :2*/
O(n)
keep int digits[] = new int[10];
every time encounter with digit i increase value of digits[i]++
the return the max of digits array and its index. that's all.
Here is my Java code:
public static int countMaxOccurence(String s) {
int digits[] = new int[10];
for (int i = 0; i < s.length(); i++) {
int j = s.charAt(i) - 48;
digits[j]++;
}
int digit = 0;
int count = digits[0];
for (int i = 1; i < 10; i++) {
if (digits[i] > count) {
count = digits[i];
digit = i;
}
}
System.out.println("digit = " + digit + " count= " + count);
return digit;
}
and here are some tests
System.out.println(countMaxOccurence("12365444433212"));
System.out.println(countMaxOccurence("1111111"));
declare a count[] array
and change your find function to something like
//for (i = 1 to n)
{
count[numberStr.charAt(i)]++;
}
then find the largest item in count[]
public class Demo{
public static void main(String[] args) {
System.out.println("Result: " + maxOccurDigit(327277));
}
public static int maxOccurDigit(int n) {
int maxCount = 0;
int maxNumber = 0;
if (n < 0) {
n = n * (-1);
}
for (int i = 0; i <= 9; i++) {
int num = n;
int count = 0;
while (num > 0) {
if (num % 10 == i) {
count++;
}
num = num / 10;
}
if (count > maxCount) {
maxCount = count;
maxNumber = i;
} else if (count == maxCount) {
maxNumber = -1;
}
}
return maxNumber;
}}
The above code returns the digit that occur the most in a given number. If there is no such digit, it will return -1 (i.e.if there are 2 or more digits that occurs same number of times then -1 is returned. For e.g. if 323277 is passed then result is -1). Also if a number with single digit is passed then number itself is returned back. For e.g. if number 5 is passed then result is 5.

Categories