Illegal Start of Expression - java

** Problem statement:
You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can know that maximum number of topics.
Note Suppose a, b, and c are three different people, then (a,b) and (b,c) are counted as two different teams.
Input Format
The first line contains two integers, N and M, separated by a single space, where N represents the number of people, and M represents the number of topics. N lines follow.
Each line contains a binary string of length M. If the ith line's jth character is 1, then the ith person knows the jth topic; otherwise, he doesn't know the topic.
Constraints
2≤N≤500
1≤M≤500
Output Format
On the first line, print the maximum number of topics a 2-person team can know.
On the second line, print the number of 2-person teams that can know the maximum number of topics.
** Problem:
I have 2 errors ("illegal start of expression" and " ';' expected") when I want to declare the 2 numbers maxTopic and numTeam as:
public static int maxTopic = 0;
public static int numTeam = 0;
** Code:
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int ppl = in.nextInt(); // Number of people
int topic = in.nextInt(); // Number of topics
int A[]; // Array A to store information about topics known by everyone
public static int maxTopic = 0; // Maximum number of topics known
public static int numTeam = 0; // Maximum number of teams that know maxTopic
/* Read the information about topics
and save it to the array A */
for (int i = 0; i < ppl; i++)
A[i] = in.nextInt();
/* Now call the method addCheck() to check each pair of people */
for (int i = 0; i < ppl; i++)
for (int j = i + 1; j < ppl; j++)
Solution.addCheck(A[i], A[j], topic);
System.out.println(maxTopic);
System.out.println(numTeam);
}
/**
* Method used to add up 2 given numbers, check their sum,
* and update the values of maxTopic and numTeam (if possible)
* #param a First number
* #param b Second number
* #param digit Number of digits for a and b
*/
public void addCheck(int a, int b, int digit) {
int sum = a + b; // Calculate the sum of a and b
int numTopic = 0; // Number of topics known for a and b
boolean update = false; // True if the current pair has been used to update numTeam
for (int i = 1; i <= digit; i++) {
if (Solution.getNthDigit(sum, i) != 0)
numTopic++;
if (numTopic > maxTopic)
maxTopic = numTopic;
if ((update == false) && (maxTopic == numTopic)) {
numTeam++;
update = true;
}
}
}
/**
* Get the nth digit of an integer
* #param number The number being considered
* #param n The digit (starting from 1, counted from right to left)
* #return int The value of the nth digit
* Example: getNthDigit(123, 10, 1) produces 3
*/
public int getNthDigit(int number, int n) {
return (int) ((number / Math.pow(10, n - 1)) % 10);
}
}

You can't use public static modifiers within a method. Those are used for class-level declarations only. Since you use the variables in other methods, declare them in the class. Note, your addCheck method should be declared static.

Related

the output of my Interpolation search is wrong, why?

I have to write a Program which is called "Interpolation search". I came so far but now I am stuck and can´t find the error in my code.
The method split() makes a problem. This method should give me the index to split. I just typed the formula in this method. Now the big problem is, I every time get 1 as an output which is always the "leftBoundary". For example, I write in my terminal java Search 4 1 2 3 4 5 6 then I get every time 1. Why? what is wrong?
edit:
I was asked to explain what the split method does in Detail:
This method uses the formula (look at added picture) to determine where to split the (sorted) array and returns the corresponding index.
In the picture: v = wantedValue, l = leftBoundary, r = rightBoundary
enter image description here
import java.util.Scanner;
public class Search {
// This method uses the formula (look at added picture) to determine where to split the (sorted) array and returns the corresponding index.
private static int split(int[] haystack, int needle, int left, int right) {
if(haystack[right] == haystack[left]) {
return left;
}else {
needle = left + ((needle - haystack[left]) / (haystack[right] - haystack[left])) * (right - left);
return needle;
}
}
private static int search(int[] haystack, int needle) {
return -1;
}
public static void main(String[] args) {
int[] array = new int[args.length];
int leftBoundary = 1;
int rightBoundary = array.length - 1;
int wantedValue = Integer.parseInt(args[0]);
for(int i = 1; i < args.length; i++) {
array[i] = Integer.parseInt(args[i]);
}
int splitAtIndex = split(array, wantedValue, leftBoundary, rightBoundary);
System.out.println(splitAtIndex);
}
}
I tried to debug but with no success and also searched here on stackoverflow. Many have question to interpolation search, but the answers are complex and unfortunately do not explain the exact problem I have
Apart from the comment, by #user16320675, to your question, your initialization is wrong.
The first [command-line] argument is the value of wantedValue. The remaining [command-line] arguments are the elements of array.
Also, leftBoundary should be 0 (zero) and not 1 (one) since you probably want to search the whole array.
Consider the following code:
public class Search {
private static int split(int[] haystack, int needle, int left, int right) {
if (haystack[right] == haystack[left]) {
return left;
}
else {
return (int) (left + ((double) (needle - haystack[left]) / (haystack[right] - haystack[left])) * (right - left));
}
}
public static void main(String[] args) {
int[] array = new int[args.length - 1];
int leftBoundary = 0;
int rightBoundary = array.length - 1;
int wantedValue = Integer.parseInt(args[0]);
for (int i = 1; i < args.length; i++) {
array[i - 1] = Integer.parseInt(args[i]);
}
int splitAtIndex = split(array, wantedValue, leftBoundary, rightBoundary);
System.out.println(splitAtIndex);
}
}
I removed the import statement since Scanner is not used. I also removed method search since it is never called.
If I run the above code using your example [command-line] arguments, i.e.
4 1 2 3 4 5 6
then method search returns 3 — which is the index of the searched-for element in the array since 4 is the searched-for value and the array contains the numbers 1 to 6 (inclusive).
Of-course, the array being searched must be sorted.
Note that if the searched-for value is smaller than the first array element, i.e. the element at index 0 (zero), method search will return -1 (minus one) and if the searched-for value is greater than the last element in the array, method search will return the array length. Hence you can determine whether the searched-for value is not found in the array.
If the [command-line] arguments are:
4 1 2 3 5 6
then method search returns 2. Note that the searched-for value, i.e. 4, is not in the array.
It is probably also a good idea to check the parameters of method search, i.e. that right should not be less than left and that haystack contains at least one element.

Shortest subsequence length for a given sum Memoized solution giving wrong answer

The Bruteforce approach to find the shortest subsequence length for a given sum is giving the correct 2,2,9 outputs for the inputs given in the main method but when memoized getting wrong output 3,3,9. Can anyone help with this please? Thanks.
class ShortestSubsequenceWithSum {
public static int shortestSubsequenceWithSum(int[] num, int s, int cnt, Integer []dp) {
if(s == 0){
return cnt;
}
if(s < 0){
return Integer.MAX_VALUE;
}
if(dp[s] != null){
return dp[s];
}
int res = Integer.MAX_VALUE;
for(int i=0; i<num.length; i++){
int rem = s - num[i];
int ways = shortestSubsequenceWithSum(num, rem, cnt +1, dp);
res = Math.min(res, ways);
dp[s] = res;
}
// System.out.println("Returning value at # " + s);
return dp[s];
}
public static void main(String[] args) {
int[] num = {1, 1, 2, 3};
Integer dp[] = new Integer[5+1];
System.out.println(shortestSubsequenceWithSum(num, 5,0, dp));
num = new int[]{1, 2, 7, 1};
dp = new Integer[9+1];
System.out.println(shortestSubsequenceWithSum(num, 9,0, dp));
num = new int[]{1};
dp = new Integer[9+1];
System.out.println(shortestSubsequenceWithSum(num, 9,0, dp));
}
}
The problem here is that the way your recursive method works at present isn't amenable to memoization.
It looks like you are using your dp array to store the currently-known minimum count of numbers required to make a total. So dp[5] will be the minimum count of numbers required to make a total of 5. If dp[5] = 3 then you have found a way to make a total of 5 from three numbers, but not yet found a way to make 5 from fewer than three numbers.
Your method shortestSubsequenceWithSum presently returns the minimum count of numbers required to reach the total plus the number of recursive calls currently made. If you want to use memoization you will have to adjust this method to return the minimum count of numbers required to reach the total, regardless of how many levels of recursion there have so far been.
The changes you will need to make are:
In the handling for the case s == 0, return 0 rather than cnt. This represents being able to make a total of 0 from zero numbers.
Change the line dp[s] = res to dp[s] = res + 1. res contains the (minimum) count of numbers that make up s - num[i] for each value of i so far, so we add 1 for choosing num[i] in a combination that adds up to s.
These should be enough to get your code working. However, you can in fact move the line dp[s] = res + 1 immediately outside the for loop: we may as well wait for the final value of res before assigning it to dp[s]. You can also remove the parameter cnt from your method shortestSubsequenceWithSum, and all the calls to this method, as this parameter isn't being used any more.
This should leave you with the following:
/**
* Returns the minimum count of numbers from the given array that can
* make up a total. The same number can be chosen multiple times.
* #param num The numbers that can be chosen from.
* #param s The total to reach.
* #param dp An array that memoizes pre-computed values of this method.
* #return The minimum count of numbers from 'num' that totals 's'.
*/
public static int shortestSubsequenceWithSum(int[] num, int s, Integer []dp) {
if(s == 0){
return 0;
}
if(s < 0){
return Integer.MAX_VALUE;
}
if(dp[s] != null){
return dp[s];
}
int res = Integer.MAX_VALUE;
for(int i=0; i<num.length; i++){
int rem = s - num[i];
int ways = shortestSubsequenceWithSum(num, rem, dp);
res = Math.min(res, ways);
}
dp[s] = res + 1;
// System.out.println("Returning value at # " + s);
return dp[s];
}
Finally, I'll note that this code does not handle the case that there are no combinations that add up to the total. I'll leave fixing that as an exercise for you, see below for an example test case:
int[] num = {2, 4, 6};
Integer dp[] = new Integer[5+1];
System.out.println(shortestSubsequenceWithSum(num, 5, dp));

output is not correct(Swapping the first and last digit of a number)

the output is almost correct except the first digit is not being removed.
the code should swap the first and last digit of the number for example - if the input is 756 it should give 657 as output right now the code is showing 7657 the first digit is not being removed. –
package questionsOnLoops;
import java.lang.Math;
import java.util.Scanner;
public class OSJIDS {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner srv = new Scanner(System.in);
System.out.println("Enter any number: ");
int n = srv.nextInt();
int temp = n; //input number
int c = 0;
int f =n; //first digit
int l; //last digit
int result;
while(temp>0) {
temp = temp/10;
c = c+1;
}
while(f>=10) {
f = f/10;
}
g = n%10;
result = (n/10)*10+f;
result = (int) ((result%Math.pow(10,c))+(g*Math.pow(10,c)));
System.out.println(result);
}
}
I do recommend making your variables a bit more descriptive, but that is an easy fix. I am guessing from your title that you want to swap the first and last digits? This method converts the numbers to strings, making appends and insertions relatively easier in this case.
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) {
Scanner srv = new Scanner(System.in);
System.out.println("Enter any number: ");
int num = srv.nextInt();
int lastDig = num;
int firstDig = num%10;
int len = 0;
while(lastDig>9) {
lastDig/=10;
len++;
}
String ans = Integer.toString(num).substring(1, len);
ans = firstDig+ans+lastDig;
System.out.println(ans);
}
}
Let’s use your example input, 756.
This gets rid of the last digit, 6, and instead puts the first digit there:
result = (n/10)*10+f;
So now result is 757. Next you try to put the 6 where the first 7 is:
k = (int) ((result%Math.pow(10,c))+(g*Math.pow(10,c)));
This isn’t quite correct. c is 3, the number of digits. So Math.pow(10,c) equals 1000.0. But you needed to use 100 in those two places, first to get rid of the 7 and then to add the 6 there. Try subtracting 1 from c in the expression.
My suggestions for more readable code
Don’t declare a variable until you use it; inirialize each in the declaration.
Use better variable names. For example:
input rather than n
length or numberOfDigits instead of c
firstDigit instead of f
lastDigit instead of g
lastDigitReplaced instead of result
finalResult instead of k
Your code makes it quite hard to see what is exectly happening.
There are a few problems I see in your code (next to readability).
You were able to detect the first and the last number, but getting to the result seems to contain some mistakes
result = (input/10)*10+f; here you take the input (506), you divide it by 10, multiply it by 10 to abuse the the int so that your fractions are removed and restored to the original number. Then you append the first number again.
With the calculation you did above, you removed the last number, and added the first number as the last number. You are still missing the step to add the first number. It would be easier and better to just create a new number based on your calculations
Calculating the new number
You already have most of the ingredients to calculate the new number.
You already have the firstDigit and the last digit calculated. To get to the result we take the last number, and multiply it with 10 until it's in the correct position to be first.
Next we append the first number, so that it's last in our new number
finally, we add the inbetween numbers again. (you can calculate the inbetween numbers by removing the first and last number from the original input)
I've updated your code example with the above mentioned changes. I've also gave the variables a bit more clear names to indicate what they contain
public static void main(String[] args) {
Scanner srv = new Scanner(System.in);
System.out.println("Enter any number: ");
int input = srv.nextInt();
int temp = input;
int length = 0;
int firstDigit =input;
int lastDigit;
int inbetweenNumbers;
while(temp>0) {
temp = temp/10;
length = length+1;
}
while(firstDigit>=10) {
firstDigit = firstDigit/10;
}
lastDigit = input%10;
inbetweenNumbers = input - lastDigit;
inbetweenNumbers -= firstDigit * (int)Math.pow(10,length-1);
//calculating the result
int result = 0;
result += lastDigit * (int)Math.pow(10,length-1);
//Add last number (first digit of the input)
result += firstDigit;
//add the other numbers back
result+= inbetweenNumbers;
System.out.println(result+" "+length);
}

find a missing number using limited memory

The problem is, given an input file with four billion unique integers, provide an algorithm to generate an integer which is not contained in the file, assume only have 10 MB of memory.
Searched for some solutions and posted code below, one of which is to store integers into bit-vector blocks (each block representing a specific range of integers among 4 billion range, each bit in the block represent for an integer), and using another counter for each block, to count the number of integers in each block. So that if number of integers is less than the block capacity for integers, scan the bit-vector of the block to find which are missing integers.
My question for this solution is, why "the nearer to the middle that we pick, the less memory will be used at any given time", here are more context,
The array in the first pass can fit in 10 megabytes, or roughly 2^23 bytes, of memory. Since each element in the array is an int, and an int is 4 bytes, we can hold an array of at most about 2^21 elements. So, we can deduce the following:
Therefore, we can conclude the following:
2^10< rangeSize <2^26, and these conditions give us a good amount of "wiggle room," but the nearer to the middle that we pick, the less memory will be used at any given time.
public class QuestionB {
public static int bitsize = 1048576; // 2^20 bits (2^17 bytes)
public static int blockNum = 4096; // 2^12
public static byte[] bitfield = new byte[bitsize/8];
public static int[] blocks = new int[blockNum];
public static void findOpenNumber() throws FileNotFoundException {
int starting = -1;
Scanner in = new Scanner (new FileReader ("Chapter 10/Question10_3/input_file_q10_3.txt"));
while (in.hasNextInt()) {
int n = in.nextInt();
blocks[n / (bitfield.length * 8)]++;
}
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] < bitfield.length * 8){
/* if value < 2^20, then at least 1 number is missing in
* that section. */
starting = i * bitfield.length * 8;
break;
}
}
in = new Scanner(new FileReader("Chapter 10/Question10_3/input_file_q10_3.txt"));
while (in.hasNextInt()) {
int n = in.nextInt();
/* If the number is inside the block that’s missing
* numbers, we record it */
if (n >= starting && n < starting + bitfield.length * 8) {
bitfield [(n-starting) / 8] |= 1 << ((n - starting) % 8);
}
}
for (int i = 0 ; i < bitfield.length; i++) {
for (int j = 0; j < 8; j++) {
/* Retrieves the individual bits of each byte. When 0 bit
* is found, finds the corresponding value. */
if ((bitfield[i] & (1 << j)) == 0) {
System.out.println(i * 8 + j + starting);
return;
}
}
}
}
public static void main(String[] args) throws FileNotFoundException {
findOpenNumber();
}
}
If you form M blocks each of size 2^32/M, the total memory required is M+2^27/M words (32 bits). This function reaches a minimum when M=√2^27, which is halfway between 1 and 2^27 blocks. The minimum is 2^14.5 words, about 92 KBytes.
This is very clear on a bilogarithmic plot.
I like this question. I'll give it additional thought but I think if disk space and time is not an issue, you can break the numbers into 100k blocks, and sort them in each file. Any block that doesn't have 100k entries will have a gap. It's not elegant at all but it gets the ball rolling.

Coin change algorithm always returning one

/**
*
* #param d
* currency divisions
* #param p
* target
* #return number of coins
*/
public static int change(int[] d, int p) {
int[] tempArray = new int[p*2]; // tempArray to store set
// of coins forming
// answer
for (int i = 1; i <= p; i++) { // cycling up to the wanted value
int min = Integer.MAX_VALUE; //assigning current minimum number of coints
for (int value : d) {//cycling through possible values
if (value <= i) {
if (1 + tempArray[i - value] < min) { //if current value is less than min
min = 1 + tempArray[1 - value];//assign it
}
}
}
tempArray[i] = min; //assign min value to array of coins
}
return tempArray[p];
}
Can anyone help me see why this is not working please? The method is meant to be given an input of values representing coins, it has an infinite number of these coints with which to form the integer p, the method is to return the minimum number of coins used to get to p.
tempArray is initialized to 0 on all indices.
using tempArray[1-value] is basically giving you 0.
So, all indices from 1 to p has the value 1 + tempArray[1-value]
This is 1. Also, tempArray[1-value] is a negetive index. I think you meant tempArray[i-value]

Categories

Resources