This question already has an answer here:
Can you quickly tell me if this pseudocode makes sense or not?
(1 answer)
Closed 9 years ago.
I believe my code is now foolproof. I will write up the pseudocode now. But I do have one question. Why does DRJava ask that I return something outside of my if statements? As you can see I wrote for ex: "return 1;" just because it asked. It will never return that value however. Can someone explain this to me?
public class assignment1question2test {
public static void main(String[] args) {
int[] a = new int[1];
int l = 0;
int r = a.length-1;
for(int i=0; i<=r; i++) {
a[i] = 1;
}
a[0] = 10;
for (int i=0; i<=r; i++) {
System.out.println(a[i]);
}
System.out.print(recursiveSearch(a,l,r));
}
public static int recursiveSearch (int[] a, int l, int r) {
int third1 = (r-l)/3 + l;
int third2 = third1*2 - l + 1;
if (r-l == 0) {
return l;
}
System.out.println("i will be checking compare from " + l + " to " + third1 + " and " + (third1 + 1) + " to " + third2);
int compareResult = compare(a,l,third1,third1 + 1, third2);
if(r-l == 1) {
if (compareResult == 1) {
return l;
}
else {
return r;
}
}
if (compareResult == 0) {
return recursiveSearch(a,third2 + 1, r);
}
if (compareResult == 1) {
return recursiveSearch(a,l,third1);
}
if (compareResult == -1) {
return recursiveSearch(a,third1 + 1, third2);
}
return 1;
}
public static int compare(int[] a, int i, int j, int k, int l) {
int count1 = 0;
int count2 = 0;
for(int g=i; g<=j; g++) {
count1 = count1 + a[g];
}
for(int g=k; g<=l; g++) {
count2 = count2 + a[g];
}
if (count1 == count2) {
return 0;
}
if (count1 > count2) {
return 1;
}
if (count1 < count2) {
return -1;
}
return 0;
}
}
FINAL PSEUDOCODE I THINK
Algorithm: recursiveSearch (a,l,r)
Inputs: An array a, indices l and r which delimit the part of interest.
Output: The index that has the lead coin.
int third1 ← (r - l)/3
int third2 ← third1*2 - l + 1
if (r-l = 0) then
return l
int compareResult ← compare(a,l,third1,third1 + 1,third2)
if (r-l = 1) then
if (compareResult = 1) then
return l
else
return r
if (compareResult = 0) then
return recursiveSearch(a, third2 + 1, r)
if (compareResult = "1") then
return recursiveSearch(a,l,third1)
if (compareResult = "-1") then
return recursiveSearch(a,third1 + 1,third2)
String compareResult ← compare(a,l,mid,mid,r)
Here you check the middle element twice, make it:
String compareResult ← compare(a,l,mid,mid+1,r)
Apart from that your algorithm seems fair enough to me.
You should refine you logic more, it doesn't consider the case where the number of coin is even.
Odd: take a coin out, divide the remaining into 2 equal half and do the comparison.
Even: divide the remaining into 2 equal half and do the comparison.
For recursive function, please also define the base case:
When n=1, return the coin.
When n=2, return the heavier coin.
NumberOfCoin = r-l+1
if (NumberOfCoin = 1)
return l;
if (NumberOfCoin = 2)
compare(a,l,l,r,r)
0: Think it yourself
-1: Think it yourself
1: Think it yourself
if (NumberOfCoin is odd number)
mid = Think it yourself
compare(a, l, mid-1, mid+1, r)
0: Think it yourself
-1: Think it yourself
1: Think it yourself
if (NumberOfCoin is even number)
mid = l+r/2
compare(a, l, mid, mid+1, r)
0: Think it yourself
-1: Think it yourself
1: Think it yourself
Related
In the Recursion when I write res += countNatNum(++len, sum + i, k, d); I have a StackOverFlow mistake. But when I change pre-increment on len + 1 res res += countNatNum(len + 1, sum + i, k, d); everything is OK. I don't understand why does it happen because I check the condition with if (len == 3) ?
public static int countNatNum(int len, int sum, int k, int d){
int base = 9;
if (d > base * k) return 0;
else if (len == k){
if (sum == d){
return 1;
}
else return 0;
}
int res = 0;
int c = (len == 0 ? 1 : 0);
for (int i = c; i <= base; i++){
res += countNatNum(len + 1, sum + i, k, d);
}
return res;
}
}
The Program should count the number of natural numbers where sum of digits == another natural number. The program works correct but i don't understand why does pre-increment works in such strange way.
If you use "++" the updated value is stored again. ""len +1" on the other hand does not increment "len".
This code, generates a random number, sorts it in ascending order and does the binary search to find a target value. MY QUESTION IS HOW DO I MODIFY THIS CODE TO FIND THE LARGEST INDEX OF THE GIVEN TARGET. For example the array has { 1, 2 , 3, 5, 5, 5, 5}, the target is 5, so the output should be 6 instead of 3. Thankyou.
import java.util.*;
public class Sort
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
System.out.print("How many numbers do you want? ");
int howMany = in.nextInt();
int [] myArray = getSortedRandomArray(howMany);
System.out.print("\nFor what value would you like to search? ");
int target = in.nextInt();
int index = bsearch ( myArray, target);
if (index >= 0)
{
System.out.println("The value " + target + " occurs at index " + index);
}
else
{
System.out.println("The value " + target + " does not occur in the array. ");
}
}
public static int bsearch(int[] arr, int key)
{
int lo = 0, hi = arr.length - 1;
{
while (lo < hi)
{
int mid = (lo + hi) / 2;
if (arr[mid] <= key)
lo = mid + 1;
if (arr[mid] > key)
hi = mid;
}
if (arr[lo] == key) {
return lo;
}
else if ((arr[lo] != key) && (arr[lo-1] == key)){
return lo - 1;
}
else{
System.out.print("The value " + key + " does not occur in the array. ");
}
return -1 ;
}
public static int[] getSortedRandomArray (int howMany)
{
int[] returnMe = new int [howMany];
Random rand = new Random();
for (int i = 0; i < howMany ; i++)
returnMe[i] = rand.nextInt(Integer.MAX_VALUE) + 1;
for (int i = 1; i <= (howMany - 1); i++)
{
for (int j = 0; j <= howMany - i -1; j++)
{
int tmp = 0;
if (returnMe[j] > returnMe[j+1])
{
tmp = returnMe[j];
returnMe[j] = returnMe[j + 1];
returnMe[j + 1] = tmp;
}
}
}
System.out.print("Here is a random sorted array: ");
for ( int i = 0; i < howMany; i++)
System.out.print(returnMe[i] + " ");
return returnMe;
}
You can do this by modifying the binary search algorithms code like this:
public static int bsearch(int[] arr, int key) {
int lo = 0, hi = arr.length - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (arr[mid] <= key)
lo = mid + 1;
if (arr[mid] > key)
hi = mid;
}
if (arr[lo] == key) {
return lo;
}
else {
return lo - 1;
}
}
This code instead searches for the first number larger than key. That can be any number, 6 or 10000, it doesn't matter. As you can see, if arr[mid] is equal to key, the code will still run on the interval [mid, hi]. Why those two returns at the end? Well if input array is like the one you gave, lo will end being the index of the last 5, but if we add another number at the end of input array, lo will be index of the number behind the last 5. Therefore, we have 2 different cases.
Also, you can't do it with a linear loop like other answers, because that reduces the algorithm to O(n) and it ends just being a linear search on a reduced array.
If you update your bsearch algorithm a little you can ask it to seek higher matches recursively. However whether this is more efficient than a linear loop would depend on what the input array looked like.
public static int bsearch(int[] arr, int key, int lo, int hi) {
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (arr[mid] == key) {
System.out.println("The value " + key + " is found at " + mid);
int higherResult = bsearch(arr, key, mid + 1, hi);
if (higherResult < 0) {
return mid;
}
return higherResult;
}
if (arr[mid] < key) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return -1;
}
input 3,5 output should be 3,4,5
input 5,3 output should be 5,4,3
And the code
public static void test(int a, int b) {
if(a>b) {
for (int i = a; i >= b; i--) {
System.out.print(i + "\t");
}
}else if(a<b) {
for (int i = a; i <= b; i++) {
System.out.print(i + "\t");
}
}
}
It works but looks a little messy. Is it possible to do without if else thing? Only one loop.
One solution which handle also boundary values correctly could be
public static void test(int start, int end) {
int current = start;
int stepWidth = current <= end ? +1 : -1;
while (current != (end + stepWidth)) {
System.out.print(current + "\t");
current += stepWidth;
}
System.out.println("");
}
edit Another one using a for loop.
public static void test(int start, int end) {
int stepWidth = start <= end ? 1 : -1;
for (int current = start; current != end + stepWidth; current += stepWidth) {
System.out.print(current + "\t");
}
System.out.println("");
}
executions
test(3, 5);
test(5, 3);
test(Integer.MAX_VALUE - 3, Integer.MAX_VALUE);
test(Integer.MIN_VALUE, Integer.MIN_VALUE + 3);
output
3 4 5
5 4 3
2147483644 2147483645 2147483646 2147483647
-2147483648 -2147483647 -2147483646 -2147483645
How about this version?
public static void test(int a, int b) {
int d = b > a ? 1 : -1;
for (int i = a; i != b; i+=d) {
System.out.print(i + "\t");
}
System.out.println(b);
}
This my solution, feedback appreciated.
public static void test(int a, int b) {
int middle = (a < b) ? (b - 1) : (a - 1);
System.out.println(a + "," + middle + ","+b);
}
Above will work only when a != b.
You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations:
modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
Problem Link
I am using Segment Tree for this but i am not getting the correct output , please Help me where i have committed the mistake
CODE:
Making a Tree:
public static void maketree(int current , int a , int b ,int[] arr){
if(b<a) return;
if(b==a) {dp[current] = arr[a]; return ;}
maketree(2*current, a, (a+b)/2, arr);
maketree(2*current+1,1+ (a+b)/2, b, arr);
if(dp[2*current]>0 && dp[2*current+1]>0) dp[current] = dp[2*current] + dp[2*current+1];
else if(dp[2*current]>dp[2*current+1]) dp[current] = dp[2*current];
else dp[current] = dp[2*current+1];
}
Updating Function
public static void update(int current , int a , int b , int c , int value){
if(a>b || c<a || c>b) return ;
if(a==b){ dp[current] = value; return ; }
update(2*current, a, (a+b)/2, c, value);
update(2*current+1, (b+a)/2 +1, b, c, value);
if(dp[2*current]>0 && dp[2*current+1]>0) dp[current] = dp[2*current] + dp[2*current+1];
else if(dp[2*current]>dp[2*current+1]) dp[current] = dp[2*current];
else dp[current] = dp[2*current+1];
}
Query Function:
public static int query(int current , int a , int b , int i , int j){
int ans =0;
if(a>j || b<i || a>b) return Integer.MIN_VALUE;
if(a>=i && b<=j) return dp[current];
int x = query(2*current, a, (a+b)/2, i, j);
int y = query(2*current+1, (a+b)/2 +1, b, i, j);
if(x>0 && y>0) ans= x+y;
else if(x>y) ans = x;
else ans =y;
return ans;
}
I don;t know where i have made mistake please help , What will storage capacity required for dp array i.e. size of dp
when you are merging two nodes,then it may be like given below.execute any simple example so that you can feel it :)
void merge(node a , node b)
{
sum = a.sum + b.sum;
pre = max(a.pre , (a.sum + b.pre));
suf = max(b.suf , (b.sum + a.suf));
result = max(a.suf + b.pre,max(a.result , b.result));
}
it is quite overcomplicated imo...
int tree[1 << 17]; // 2 ^ 17 >= N * 2
int M = 1; //base of tree or sth i dont remember english name
int query(int L, int R){
int res = -10000; //minimum possible value in array
L += M - 1;
R += M - 1;
while(L <= R){
if(L % 2 == 1) res = max(res, tree[L++];
if(R % 2 == 0) res = max(res, tree[R++];
L /= 2;
R /= 2;
}
return res;
}
void update(int v, int value){
v += M - 1;
tree[v] = value;
while(v > 0){
v /= 2;
tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
}
}
void make_tree(){
int n;
cin >> n;
while(M < n) M *= 2; // M is half of the size of tree
for(int i = 0;i < n;i++)
cin >> tree[i + M]; // just reading input to tree;
for(int i = M - 1;i > 0;i--) // first update for all nodes other than leafs
tree[i] = max(tree[i * 2], tree[i * 2 + 1]);
}
I believe my code is now foolproof. I will write up the pseudocode now. But I do have one question. Why does DRJava ask that I return something outside of my if statements? As you can see I wrote for ex: "return 1;" just because it asked. It will never return that value however. Can someone explain this to me?
public class assignment1question2test {
public static void main(String[] args) {
int[] a = new int[50];
int l = 0;
int r = a.length;
for(int i=0; i<r; i++) {
a[i] = 1;
}
a[0] = 10;
for (int i=0; i<r; i++) {
System.out.println(a[i]);
}
System.out.print(recursiveSearch(a,l,r));
}
public static int recursiveSearch (int[] a, int l, int r) {
int third1 = (r-l)/3 + l;
int third2 = third1*2 - l + 1;
System.out.println("i will be checking compare from " + l + " to " + third1 + " and " + (third1 + 1) + " to " + third2);
int compareResult = compare(a,l,third1,third1 + 1, third2);
if(r-l == 1) {
if (compareResult == 1) {
return l;
}
else {
return r;
}
}
if (compareResult == 0) {
return recursiveSearch(a,third2 + 1, r);
}
if (compareResult == 1) {
return recursiveSearch(a,l,third1);
}
if (compareResult == -1) {
return recursiveSearch(a,third1 + 1, third2);
}
return 1;
}
public static int compare(int[] a, int i, int j, int k, int l) {
int count1 = 0;
int count2 = 0;
for(int g=i; g<=j; g++) {
count1 = count1 + a[g];
}
for(int g=k; g<=l; g++) {
count2 = count2 + a[g];
}
if (count1 == count2) {
return 0;
}
if (count1 > count2) {
return 1;
}
if (count1 < count2) {
return -1;
}
return 0;
}
}
UPDATED FINAL PSEUDOCODE:
Algorithm: recursiveSearch (a,l,r)
Inputs: An array a, indices l and r which delimit the part of interest.
Output: The index that has the lead coin.
int third1 ← (r - l + 1)/3
int third2 ← third1*2 - l + 1
if (r-l = 0) then
return l
int compareResult ← compare(a,l,third1,third1 + 1,third2)
if (r-l = 1) then
if (compareResult = 1) then
return l
else
return r
if (compareResult = 0) then
return recursiveSearch(a, third2 + 1, r)
if (compareResult = "1") then
return recursiveSearch(a,l,third1)
if (compareResult = "-1") then
return recursiveSearch(a,third1 + 1,third2)
You seem to be including mid in the following search regardless of which side is larger. The recursive calls should both exclude mid from their search space.
Also, for the comparison to be meaningful, the two groups being compared need to be of equal size. That will require some extra odd/even logic.