Why does this binary search code give wrong output on Eclipse IDE? - java

Why does this binary search code give wrong output on Eclipse IDE but gets accepted when submitted to Coursera? This is a sample input for which it shows the wrong output.
Sample Input:
5 3 2 4 1 5
3 1 2 7
Output:
-1 -1 -1
Clearly, the element '1' is present is the input array. But the output for that is -1 instead of 3.
import java.io.*;
import java.util.*;
public class BinarySearch {
static int binarySearch(int[] a,int l,int r,int x) {
//write your code here
if(l<=r){
int mid =l + (r - l)/2;
if(x==a[mid])
return mid;
else if(x<a[mid]){
return binarySearch(a,l,mid-1,x);
}
else
return binarySearch(a,mid+1,r,x);
}
return -1;
}
public static void main(String[] args) {
FastScanner scanner = new FastScanner(System.in);
int n = scanner.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
}
int m = scanner.nextInt();
int[] b = new int[m];
for (int i = 0; i < m; i++) {
b[i] = scanner.nextInt();
}
for (int i = 0; i < m; i++) {
//replace with the call to binarySearch when implemented
System.out.print(binarySearch(a,0,n-1,b[i]) + " ");
}
}
static class FastScanner {
BufferedReader br;
StringTokenizer st;
FastScanner(InputStream stream) {
try {
br = new BufferedReader(new InputStreamReader(stream));
} catch (Exception e) {
e.printStackTrace();
}
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}

Actually, the problem is with your input data and not the code itself. If you search information about binary search you can find: "binary search is a search algorithm that finds the position of a target value within a sorted array". Your input isn't sorted.
You would have to sort the array before running the search which would be a bad idea - searching with other algorithm would take less time than sorting.
If you try to input sorted data, eg.:
5 1 2 3 4 5
3 1 2 7
The result will be 0 1 -1 - just as expected.

Related

Majority Element Algorithm Time complexity

need help to determine the time complexity for my solution to Majority Element
Problem Description
Task.
The goal of this code problem is to check whether an input sequence contains a majority element.
Input Format.
The first line contains an integer 𝑛, the next one contains a sequence of 𝑛 non-negative
integers 𝑎0, 𝑎1, . . . , 𝑎𝑛−1.
Constraints.
1 ≤ 𝑛 ≤ 105
; 0 ≤ 𝑎𝑖 ≤ 109
for all 0 ≤ 𝑖 < 𝑛.
Output Format.
Output 1 if the sequence contains an element that appears strictly more than 𝑛/2 times,
and 0 otherwise.
Sample 1.
Input:
5
2 3 9 2 2
Output:
1
public class MajorityElement {
private static int getMajorityElement( int count, int right) {
//write your code here
if ((float) count > (float) right / 2) {
return 1;
}
return -1;
}
public static void main(String[] args) {
FastScanner scanner = new FastScanner(System.in);
HashMap<String, Integer> map = new HashMap<>();
int n = scanner.nextInt();
int c = 0;
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
if (map.get(String.valueOf(a[i])) == null) {
map.put(String.valueOf(a[i]), 1);
} else {
int count;
count = map.get(String.valueOf(a[i])) + 1;
map.put(String.valueOf(a[i]), count);
if (c < count) {
c=count;
}
}
}
if (getMajorityElement( c, a.length) != -1) {
System.out.println(1);
} else {
System.out.println(0);
}
}
static class FastScanner {
BufferedReader br;
StringTokenizer st;
FastScanner(InputStream stream) {
try {
br = new BufferedReader(new InputStreamReader(stream));
} catch (Exception e) {
e.printStackTrace();
}
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}
The complexity of the function getMajorityElement is O(1), because you are doing a simple logic inside the function, but the complexity of the entire code is O(n) because you have a loop that runs n times.

How to find a number with no digit occurring more than once (J3 CCC 2013 from 1987 to 2013)

I'm a grade 11 student and have been given the task to complete this question for homework:
Problem J3/S1: From 1987 to 2013
You might be surprised to know that 2013 is the first year since 1987
with distinct digits.
The years 2014, 2015, 2016, 2017, 2018, 2019
each have distinct digits.
2012 does not have distinct digits,
since the digit 2 is repeated.
Given a year, what is the next year with distinct digits?
Input
The input consists of one integer Y (0 ≤ Y ≤ 10000),
representing the starting year.
Output
The output will be the single integer D,
which is the next year after Y with distinct digits.
Sample Input 1
1987
Sample Output 1
2013
Sample Input 2
999
Sample Output 2
1023
I usually answer these types of questions rather quickly but I am stumped when it comes to this one. I have spent several hours and cannot figure it out. I found out How to identify if a number is distinct or not, but I can't figure out how to add on years and check again, I keep getting errors. I would really appreciate someone's help.
Please keep in mind that I am in grade 11 and this is my first year of working with Java, so please do not use advanced coding, and methods because I won't understand. If you can, please answer it in a class and not the main method.
here is what I tried:
import java.util.*;
import java.io.*;
public class Leavemealone
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader(System.in));
int ctr = 0;
String inputStr = "";
int input = 0;
int inputCheck = 0;
System.out.println("Enter somthin: ");
input = Integer.parseInt (objReader.readLine ());
while(ctr == 0)
{
inputStr += input;
Scanner sc = new Scanner(inputStr);
int n = sc.nextInt(); // get year
String s = String.valueOf(n);
int[] num = new int[4];
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
num[i] += x;
}
String apple = (num[0] + "" + num[1] + "" + num[2] + "" + num[3]);
if (num[0] != num[1] &&
num[1] != num[2] &&
num[2] != num[3] &&
num[0] != num[2] &&
num[0] != num[3] &&
num[1] != num[3])
{
ctr++;
//distinct
}
else
{
input++;
//not distinct
}
}
}
}
Thanks in advance!
this is the other code I found online, I just don't know how to put it in a class
import java.util.Scanner;
import java.io.*;
public class Thegoodone
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader (System.in));
int ctr = 0;
String input = "";
int inputCheck = 0;
while (ctr == 0)
{
System.out.println("Enter somthin: ");
inputCheck = Integer.parseInt (objReader.readLine ());
if (inputCheck > 0 && inputCheck < 10000)
{
input += inputCheck;
ctr += 1;
}
else
{
System.out.println("invalid input ");
}
}
Scanner sc = new Scanner(input);
int n = sc.nextInt(); // get year
n++; // start from the next year
while (!hasDistinctDidgets(n)) //if there is repeating digits
{
n++;// next year
}
System.out.println(n);// prints year
}
public static boolean hasDistinctDidgets(int n)
{
//System.out.println("a" + n);
String s = String.valueOf(n); // converts the year from int to String
int[] numbers = new int[10]; // index position represents number, element value represents occurrence of that number
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
numbers[x]++; //increase occurrence of this integer in the array
}
//check if any digit occurred more than once in the array
for (int i = 0; i < numbers.length; i ++)
{
if (numbers[i] > 1) //digit occurred more than once
{
return false; //not distinct
}
}
return true; // hasn't returned false yet, so the integer has distinct digits
}
}
so this is how I tried to put it in a class:
import java.util.Scanner;
import java.io.*;
public class Danny3
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader (System.in));
int ctr = 0;
String input = "";
int inputCheck = 0;
while (ctr == 0)
{
System.out.println("Enter somthin: ");
inputCheck = Integer.parseInt (objReader.readLine ());
if (inputCheck > 0 && inputCheck < 10000)
{
input += inputCheck;
ctr += 1;
}
else
{
System.out.println("invalid input ");
}
}
Scanner sc = new Scanner(input);
// System.out.println(output);
int n = sc.nextInt(); // get year
n++; // start from the next year
DistinctCheck processing = new DistinctCheck(n);
int output = processing.getSum();
System.out.println(output);
}
}
class DistinctCheck
{
//private int year = 0;
private boolean hasDistinctDidgets;
private int b = 0;
DistinctCheck(int temp)
{
hasDistinctDidgets(temp);
}
private void yearAdd(int b)
{
while(!hasDistinctDidgets(b)) //if there is repeating digits
{
b++;// next year
}
}
private boolean hasDistinctDidgets(int year)
{
String s = String.valueOf(year); // converts the year from int to String
int[] numbers = new int[10]; // index position represents number, element value represents occurrence of that number
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
numbers[x]++; //increase occurrence of this integer in the array
}
//check if any digit occurred more than once in the array
for (int i = 0; i < numbers.length; i ++)
{
if (numbers[i] > 1) //digit occurred more than once
{
return false; //not distinct
}
}
return true; // hasn't returned false yet, so the integer has distinct digits
}
int getSum()
{
return b;// prints year
}
}
I would start with a method to determine if a given int consists of distinct digits. You could use a Set<Character> and add each character from the String to the Set. You will get false on a duplicate. Like,
static boolean distinctDigits(int i) {
String s = String.valueOf(i);
Set<Character> set = new HashSet<>();
for (char c : s.toCharArray()) {
if (!set.add(c)) {
return false;
}
}
return true;
}
Then your main just needs to invoke that. Like,
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int v = s.nextInt();
while (v < 10000) {
v++;
if (distinctDigits(v)) {
break;
}
}
System.out.println(v);
}
i figured it out:
import java.util.*;
public class Apple
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int num = input.nextInt();
Distinct findDistinct = new Distinct(num); // objecct
String output = findDistinct.getDistinctYear();
System.out.println(output);
}
} // end of main
class Distinct
{
private int ctr = 0;
private String yearStr = "";
private String distinctYear = "";
private int year = 0;
Distinct(int n)
{
year = n;
makeDistinct();
}
private void makeDistinct()
{
while(ctr == 0)
{
year += 1; // year will keep increasing until it is distinct
yearStr = Integer.toString(year);
if(isDistinct(yearStr) == true) // if the number is distinct
{
distinctYear = yearStr;
ctr++;
}
}
}
private boolean isDistinct(String yearStr)
{
String eachNum[] = yearStr.split(""); // breaks up each number (char) of yearStr
for(int i = 0; i < eachNum.length; i++)
{
for(int j = 0; j < i; j++)
{
if (eachNum[i].equals(eachNum[j])) // not distinct
{
return false;
}
}
}
return true; // is distinct
}
String getDistinctYear()
{
return distinctYear;
}
}

How to save a deleted character with stringbuilder

Is it possible to save a character which was deleted with the Stringbuffer or delete all character except one on 'i' index
This is my input from a txt file:
3;8;4;5;3;2
3 4 5 1 2 3
9;8;3;2;3;4
9 8 9 7 8 1
I need to sum up each line and see in which one is most of even numbers, so i decided to read a whole line, separate characters with a space then with help of string builder delete all characters except one on 'i' position and finally save in two dimentional array.
Maybe you'll have some better idea how to do it?
My code:
package Operacje_na_plikach;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class Zad3 {
/*
Plik tekstowy ‘dane.txt’ ma postać:
3;8;4;5;3;2
3 4 5 1 2 3
9;8;3;2;3;4
9 8 9 7 8 1
Pobierz z pliku tekstowego kolejne wiersze liczb i wypisz na ekranie numer wiersza, w którym występuje najwięcej elementów parzystych.
*/
public static String[][] odczyt(String nazwa)
{
String[][] arr = new String[1][1];
int[] suma = new int[1];
int max = -1;
int wiersz=-1;
String text = null;
try {
FileReader reader = new FileReader(nazwa);
Scanner sc = new Scanner(reader);
while(sc.hasNextLine())
{
arr=Arrays.copyOf(arr,arr.length+1);
text = sc.nextLine().replaceAll(";"," ");
int[] temp= new int[text.length()];
StringBuilder sb = new StringBuilder(text);
for (int i = 0; i <temp.length ; i++) {
temp[i]=sb.delete();
}
for (int i = 0; i < ; i++) {
for (int j = 0; j < ; j++) {
arr[i][j] = text
}
}
}
/* while (sc.hasNextLine())
{
arr=Arrays.copyOf(arr,arr.length+1);
text = sc.nextLine().replaceAll("[;]"," ");
for (int i = 0; i <arr.length ; i++) {
while(text!=null)
{
int temp = Integer.parseInt(text);
}
for (int j = 0; j <arr.length ; j++) {
arr[i][j] = text.nextInt();
if(arr[i][j]%2==0)
{
suma[i]+=arr[i][j];
if(suma[i]>max)
{
max = suma[i];
wiersz=i;
}
}
}
}
}
System.out.println("Najwiecej liczb parzystych jest w wierszu: " + wiersz);
*/
sc.close();
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return arr;
}
public static void main(String[] args) {
int[][] arr = odczyt("dane.txt");
}
}
I think you may be over-complicating things. You could stream the lines of the file, parse them, and map them to the sum of the even numbers. You can then go over the array of sums and find the index of the largest element (which can also be done with streams, just for the fun of it):
long[] sums =
Files.lines(Paths.get("dane.txt"))
.mapToLong(s -> Arrays.stream(s.split("[ ;]"))
.mapToInt(Integer::parseInt)
.filter(i -> i % 2 == 0)
.sum())
.toArray();
int lineNum =
IntStream.range(0, sums.length)
.boxed()
.max(Comparator.comparingLong(i -> sums[i]))
.get();

Java program not outputting negative integers from array?

One of my Java assignments is to take numbers from a file and then seperate them to two arrays. One named P (positive numbers) and N (negative numbers.) I have it working for the positive numbers but the negative numbers keep outputting 0s. I have no idea why! Help?
import java.io.*;
import java.util.*;
public class Prog404a {
public static void main(String[] args) {
Scanner inFile = null;
try {
inFile = new Scanner(new File("prg404a1.dat"));
} catch (FileNotFoundException e) {
System.out.println("File not found!!");
System.exit(0);
}
int temp = 0;
int P[] = new int[23];
int N[] = new int[23];
int i = 0;
while (inFile.hasNext()) {
temp = inFile.nextInt();
if (temp < 0) {
N[i] = temp;
}
if (temp > 0) {
P[i] = temp;
}
i++;
}
for (int x = 0; x < i; x++) {
System.out.println(P[x] + "\t" + N[x]);
}
}
}
EDIT: Never mind it's not working for positive numbers either. Only a few.
Maybe you are just not counting right?
You should be using two counters, one for positive, one for negative numbers.
Otherwise, half of the entries will obviously be 0, because they were never set.

interviewstreet.com - String similarity

I'm trying to solve the string similarity question on interviewstreet.com. My code is working for 7/10 cases (and it is exceeding the time limit for the other 3).
Here's my code -
public class Solution {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
String v1 = user_input.next();
int number_cases = Integer.parseInt(v1);
String[] cases = new String[number_cases];
for(int i=0;i<number_cases;i++)
cases[i] = user_input.next();
for(int k=0;k<number_cases;k++){
int similarity = solve(cases[k]);
System.out.println(similarity);
}
}
static int solve(String sample){
int len=sample.length();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(sample.charAt(j-i)==sample.charAt(j))
sim++;
else
break;
}
}
return sim;
}
}
Here's the question -
For two strings A and B, we define the similarity of the strings to be the length of the longest prefix common to both strings. For example, the similarity of strings "abc" and "abd" is 2, while the similarity of strings "aaa" and "aaab" is 3.
Calculate the sum of similarities of a string S with each of it's suffixes.
Input:
The first line contains the number of test cases T. Each of the next T lines contains a string each.
Output:
Output T lines containing the answer for the corresponding test case.
Constraints:
1 <= T <= 10
The length of each string is at most 100000 and contains only lower case characters.
Sample Input:
2
ababaa
aa
Sample Output:
11
3
Explanation:
For the first case, the suffixes of the string are "ababaa", "babaa", "abaa", "baa", "aa" and "a". The similarities of each of these strings with the string "ababaa" are 6,0,3,0,1,1 respectively. Thus the answer is 6 + 0 + 3 + 0 + 1 + 1 = 11.
For the second case, the answer is 2 + 1 = 3.
How can I improve the running speed of the code. It becomes harder since the website does not provide a list of test cases it uses.
I used char[] instead of strings. It reduced the running time from 5.3 seconds to 4.7 seconds and for the test cases and it worked. Here's the code -
static int solve(String sample){
int len=sample.length();
char[] letters = sample.toCharArray();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(letters[j-i]==letters[j])
sim++;
else
break;
}
}
return sim;
}
used a different algorithm. run a loop for n times where n is equals to length the main string. for each loop generate all the suffix of the string starting for ith string and match it with the second string. when you find unmatched character break the loop add j's value to counter integer c.
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Solution {
public static void main(String args[]) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(in.readLine());
for (int i = 0; i < T; i++) {
String line = in.readLine();
System.out.println(count(line));
}
}
private static int count(String input) {
int c = 0, j;
char[] array = input.toCharArray();
int n = array.length;
for (int i = 0; i < n; i++) {
for (j = 0; j < n - i && i + j < n; j++)
if (array[i + j] != array[j])
break;
c+=j;
}
return c;
}
}
I spent some time to resolve this question, and here is an example of my code (it works for me, and pass thru all the test-cases):
static long stringSimilarity(String a) {
int len=a.length();
char[] letters = a.toCharArray();
char localChar = letters[0];
long sim=0;
int sameCharsRow = 0;
boolean isFirstTime = true;
for(int i=0;i<len;i++){
if (localChar == letters[i]) {
for(int j = i + sameCharsRow;j<len;j++){
if (isFirstTime && letters[j] == localChar) {
sameCharsRow++;
} else {
isFirstTime = false;
}
if(letters[j-i]==letters[j])
sim++;
else
break;
}
if (sameCharsRow > 0) {
sameCharsRow--;
sim += sameCharsRow;
}
isFirstTime = true;
}
}
return sim;
}
The point is that we need to speed up strings with the same content, and then we will have better performance with test cases 10 and 11.
Initialize sim with the length of the sample string and start the outer loop with 1 because we now in advance that the comparison of the sample string with itself will add its own length value to the result.
import java.util.Scanner;
public class StringSimilarity
{
public static void main(String args[])
{
Scanner user_input = new Scanner(System.in);
int count = Integer.parseInt(user_input.next());
char[] nextLine = user_input.next().toCharArray();
try
{
while(nextLine!= null )
{
int length = nextLine.length;
int suffixCount =length;
for(int i=1;i<length;i++)
{
int j =0;
int k=i;
for(;k<length && nextLine[k++] == nextLine[j++]; suffixCount++);
}
System.out.println(suffixCount);
if(--count < 0)
{
System.exit(0);
}
nextLine = user_input.next().toCharArray();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Categories

Resources