I'm trying to make a calculator for very big numbers (even bigger than long long) and I'm using arrays to make it work.
So far I have done addition, subtraction and multiplication. But I'm really stuck in division part.
EDIT:
new progress. as a friend mentioned i need to compare result array with divisor each time so i can stop the progress any time divisor is larger than dividend. I managed to make a nice function to compare it every time. this function is tested separately and it's working fine. OK. now i'm starting to make REAL progress. i got the quotient. now i will try to put quotient in array so that we can work with LARGER numbers!
#define MAX_SIZE 50
#define SIZE_USE (MAX_SIZE-1)
int div(int inum_first[], int inum_second[], int div_result[], int firstlen, int secondlen)
{
int i;
int check1 = 0, check2 = 0;
int zeroC = 0;
int tmp[MAX_SIZE];
for (i = 0; i <= SIZE_USE; i++)
{
tmp[i] = 0;
}
int inum_firstCP[MAX_SIZE] = { 0 };
for (i = 0; i <= 1; i++)
{
inum_firstCP[i] = inum_first[i]; // create a copy of inum_first
}
for (i = 0; i <= SIZE_USE; i++)
{
if (inum_first[i] != 0)
check1++;
if (inum_second[i] != 0)
check2++;
}
if (secondlen > firstlen)
{
zeroC++;
goto EOI;
}
if (check2 == 0)
{
puts("\nExpected error\n");
return -1;
}
int j = 0, p = 0;
int s = 0;
int o = 1; // o is Quotient!
do
{
for (i = SIZE_USE; i >= 0; i--)
{
if (tmp[i] = inum_firstCP[i] - inum_second[i] >= 0)
{
tmp[i] = inum_firstCP[i] - inum_second[i];
}
else
{
inum_firstCP[i - 1] = inum_firstCP[i - 1] - 1;
tmp[i] = (inum_firstCP[i] + 10) - inum_second[i];
}
inum_firstCP[i] = tmp[i];
}
if (compare(inum_firstCP, inum_second, firstlen, secondlen) < 0) break;
j++;
o++;
} while (j<MAX_SIZE); // anything else will also work
EOI:
return 0;
}
int compare(int inum_firstCP[], int inum_second[], int firstlen, int secondlen)
{
int c = 0, d = 0;
int i;
firstlen = MAX_SIZE, secondlen = MAX_SIZE; // temporary. will provide a better solution ASAP
if (firstlen > secondlen)
{
return 1;
}
else if (secondlen > firstlen)
{
return -1;
}
else
{
for (i = 0; i < firstlen; i++)
{
if (inum_firstCP[i] > inum_second[i]) c++;
else if (inum_second[i] > inum_firstCP[i]) d++;
}
if (c>d) return 1;
else if (d>c) return -1;
}
return 0; // else
}
If you have the subtraction of those big numbers the easiest solution is to take the two numbers and substract one from the other until you are left with something less then zero. It is the basic solution, it works but is a bit slow.
To make it faster you can do the following, take the divisor, multiply it by 2, if it is less then the dividend, keep on multiplying. When you will reach the first number bigger then a dividend set the corresponding bit to 1, subtract the multiplied dividend then do the same for the result.
There is the same thing nicely described on wiki.
In order to make it work you need to implement your own comparing function.
Assuming you will store the size of the malloc allocation in your structure in filed len you can do something like this:
int compare( mynum &a, mynum &b){
if (a.len() > b.len()){
return 1;
} else (if b.len() > a.len()){
return -1;
} else(){
for(int i = b.len(); i > 0; i--){
if (a[i] > b[i]){
return 1;
} else if(b[i] > a[i]){
return -1;
}
}
#if we get there the numbers are the same
return 0;
}
}
I've done this before and was very happy to implement it the same way as you'd do it by hand, with a small modification of multiple subtraction at each step. The algorithm is like that:
Multiply divisor by ten as often as you can without divisor becoming bigger than dividend.
Subtract divisor from dividend as often as you can and remember how many times.
The rest of all the subtractions is the new dividend.
Repeat at step (1) until dividend is smaller than divisor.
The current dividend is the "rest".
All the numbers remembered at step (3) are the "result" when ordered left to right (left calculated first).
Okay, let's try it by example:
E.g. you have 25391 and want to divide it by 71.
(1) 25391 and 71 * 10 = 710
25391 and 710 * 10 = 7100
25391 and 7100 * 10 = 71000 <-- TOO BIG
(2) 25391 - 7100 => X
18291 - 7100 => X
11191 - 7100 => X
4091 - 7100 <--- NOT POSSIBLE
(3) Number of X: 3
(4) 4091 > 71, okay, back to step 1.
(1) 4091 and 71 * 10 = 710
4091 and 710 * 10 = 7100 <--- TOO BIG
(2) 4091 - 710 => X
3381 - 710 => X
2671 - 710 => X
1961 - 710 => X
1251 - 710 => X
541 - 710 <--- NOT POSSIBLE
(3) Number of X: 5
(4) 541 > 71, okay, back to step 1
(1) 541 and 71 * 10 = 710 <--- TOO BIG
(2) 541 - 71 => X
470 - 71 => X
399 - 71 => X
328 - 71 => X
257 - 71 => X
186 - 71 => X
115 - 71 => X
44 - 71 <--- NOT POSSIBLE
(3) Number of X: 7
(4) 44 > 71, WRONG, continue with step 5
(5) Rest is 44
(6) Result is 357
If you had just tested how often you can subtract 71 from 25391, this loop would have had 357 iterations! Of course, my solution uses multiplication, but honestly, multiplying by 10 is no real multiplication, just shift all digits one position to the left and put a zero at the top right one.
The algorithm will need as many iterations as the result has digits and it will need at most 9 iterations (with subtraction) per digit.
#Mecki Try with 54 664 455 645 655 divided by 5 465 126 544, it fails. At step 3 you must add a number of '0' corresponding to the difference of length between the divisor (x n x 10) and the "rest". ie if the rest is 13 190 205 655 (11 digits length) and divisor is 54 651 265 440 000 (14 digits length) then three '0' must be added to the result before performing the next loop.
Related
I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}
I'm understand only the code, but not it's core concept anyone explain about its flow chart and Algorithm
why we use i<=n/2 in this code is there any way to use i<=n
#include <stdio.h>
int main() {
int n, i, flag = 0;
printf("Enter a positive integer: ");
scanf("%d", &n);
for (i = 2; i <= n / 2; ++i) {
// condition for non-prime
if (n % i == 0) {
flag = 1;
break;
}
}
if (n == 1) {
printf("1 is neither prime nor composite.");
}
else {
if (flag == 0)
printf("%d is a prime number.", n);
else
printf("%d is not a prime number.", n);
}
return 0;
}
Suppose n is composite. Then n=ab for some integers a,b>1. Your first loop checks if a or b is an integer in the range [2, n/2]. If that loop never finds a factorization like that, it must be that one of the factors (if it exists) is greater than n/2. If it is greater than n/2, the other factor must be less than 2. The only such factorization is n=1n, in which case n is in fact a prime. Thus it suffices to check only factors up to n/2.
PS: I deliberately don't specify what I mean when n is odd. That's left as an exercise for you to fill in.
PPS: You can easily do a lot better than stopping at n/2. Hint: What happens when both factors are the same?
In the code you are using i <= n / 2 because for any numbers, you can't divide itself by another number greater than its half.
Let's take 29 for example (and use int, so not floating part).
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
...
29 / 14 = 2
29 / 15 = 1
29 / 16 = 1
...
Here, you see that after 14 (the half of 29), all the results are 1.
If you wish to, you can even use this formula n > i * i. Let me explain with this example. Here, we should stop at i = 5 because 29 < 6 * 6
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
===== END HERE (but let's continue to see what happens) =====
29 / 6 = 4
29 / 7 = 4
29 / 8 = 3
...
You can see that after 5, the results become smaller than the index, so you are just recalculating something that you have already calculated. It avoids timeouts on big numbers.
There is a problem which i am working on it right now and it's as the following :
there are two numbers x1 and x2 and x2 > x1.
for example x1 = 5; and x2 = 10;
and I must find the sum of ones between x1 and x2 in binary representations.
5 = 101 => 2 ones
6 = 110 => 2 ones
7 = 111 => 3 ones
8 = 1000 => 1 one
9 = 1001 => 2 ones
10= 1010 => 2 ones
so the sum will be
sum = 2 + 2 + 3 + 1 + 2 + 2 = 12 ones;
so I have managed to make a code without even transfer the numbers to binary and wasting execution time.
I noticed that the numbers of ones in every 2^n with n >= 1 is 1
Ex : 2^1 => num of ones is 1
2^2 => 1 2^15 => 1
you can test it here if you want: https://www.rapidtables.com/convert/number/decimal-to-binary.html?x=191
and between each 2^n and 2^(n+1) there are Consecutive numbers as you will see in this example :
num number of ones
2^4 = 16 1
17 2
18 2
19 3
20 2
21 3
22 3
23 4
24 2
25 3
26 3
27 4
28 3
29 4
30 4
31 5
2^5 = 32 1
so I write a code that can find how many ones between 2^n and 2^(n+1)
int t; ////turns
int bin = 1; //// numbers of ones in the binary format ,,, and 1 for 2^5
int n1 = 32; //// 2^5 this is just for clarification
int n2 = 64; //// 2^6
int *keep = malloc(sizeof(int) * (n2 - n1); ///this is to keep numbers because
/// i'll need it later in my consecutive numbers
int i = 0;
int a = 0;
n1 = 33 //// I'll start from 33 cause "bin" of 32 is "1";
while (n1 < n2) /// try to understand it now by yourself
{
t = 0;
while (t <= 3)
{
if (t == 0 || t == 2)
bin = bin + 1;
else if (t == 1)
bin = bin;
else if (t == 3)
{
bin = keep[i];
i++;
}
keep[a] = bin;
a++;
t++;
}
n1++;
}
anyway as you see I am close to solve the problem but they give me huge numbers and I must find the ones between them, unfortunately I have tried a lot of methods to calculate the "sum" using this above code and I ended up with time execution problem.
Ex: 1, 1000000000 the numbers of ones is >>> 14846928141
so can you give me a little hint what to do next, thanks in advance.
I'm doing this for CodeWar challenge: https://www.codewars.com/kata/596d34df24a04ee1e3000a25/train/c
You can solve this problem by computing the number of bits in the range 1 to n and use a simple subtraction for any subrange:
#include <stdio.h>
#include <stdlib.h>
/* compute the number of bits set in all numbers between 0 and n excluded */
unsigned long long bitpop(unsigned long long n) {
unsigned long long count = 0, p = 1;
while (p < n) {
p += p;
/* half the numbers in complete slices of p values have the n-th bit set */
count += n / p * p / 2;
if (n % p >= p / 2) {
/* all the numbers above p / 2 in the last partial slice have it */
count += n % p - p / 2;
}
}
return count;
}
int main(int argc, char *argv[]) {
unsigned long long from = 1000, to = 2000;
if (argc > 1) {
to = from = strtoull(argv[1], NULL, 0);
if (argc > 2) {
to = strtoull(argv[1], NULL, 0);
}
}
printf("bitpop from %llu to %llu: %llu\n", from, to, bitpop(to + 1) - bitpop(from));
return 0;
}
Here is a proposal for a speedup:
Find smallest y1 such that y1 >= x1 and that y1 is a power of 2
Find largest y2 such that y2 <= x2 and that y2 is a power of 2
Find p1 and p2 such that 2^p1=y1 and 2^p2=y2
Calculate the amount of 1:s between y1 and y2
Deal with x1 to y1 and y2 to x2 separately
Sum the results from 4 and 5
Let's focus on step 4. Let f(n) be the sum of ones up to (2^n)-1. We can quickly realize that f(n) = 2*f(n-1) + 2^(n-1) and that f(1)=1. This can be even further refined so that you don't have to deal with recursive calls, but I highly doubt it will be of any importance. Anyway, f(n) = n*2^(n-1)
To get the result between y1 and y2, just use f(p2)-f(p1)
For step 5, you can likely use a modified version of step 4.
EDIT:
Maybe I was to quick to say "quickly realize". Here is a way to understand it. The amounts of ones up to 2¹-1 is easy to see. The only two binary numbers below 2¹ are 0 and 1. To get the number of ones up to 2² we take the numbers below 2¹ and make a column:
0
1
Clone it:
0
1
0
1
And put 0:s before the first half and 1:s before the second half:
00
01
10
11
To get 2³ we do the same. Clone it:
00
01
10
11
00
01
10
11
And add 0 and 1:
000
001
010
011
100
101
110
111
Now it should be easy to see why f(n) = 2*f(n-1) + 2^(n-1). The cloning gives 2f(n-1) and adding the 0:s and 1:s gives 2^(n-1). If 2^(n-1) is hard to understand, remember that 2^(n-1)=(2^n)/2. In each step we have 2^n rows and half of them get an extra 1.
EDIT2:
When I looked at these columns, I got an idea for how to do step 5. Let's say that you want to find the amounts of 1:s from 10 to 15. Binary table for this would be:
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
Look at the interval 12-15. The last two digits in binary is a copy of the corresponding table for 0-3. That could be utilized, but I leave that to you.
EDIT 3:
This was a fun problem. I wrote some python code that does this. I get some problems with too many recursive calls, but that could be solved pretty easily, and it should not be too complicated to convert this to C:
def f(n):
return n*2**(n-1)
def numberOfOnes(x):
if(x==0):
return 0
p = floor(log(x,2))
a = f(p)
b = numberOfOnes(x-2**p)
c = x - 2**p +1
return a+b+c
I made an image so that you easier can understand what a, b and c does in the function numberOfOnes if we call it with numberOfOnes(12):
I have finally converted it to C. Of course I have used some code I found here on Stack overflow. I borrowed code for integer versions of log2 and pow, and made some small modifications.
This code is probably possible to optimize further, but it is not necessary. It is lighting fast, and I was not able to measure it's performance.
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <stdint.h>
#include <inttypes.h>
typedef uint64_t T;
// https://stackoverflow.com/a/11398748/6699433
const int tab64[64] = {
63, 0, 58, 1, 59, 47, 53, 2,
60, 39, 48, 27, 54, 33, 42, 3,
61, 51, 37, 40, 49, 18, 28, 20,
55, 30, 34, 11, 43, 14, 22, 4,
62, 57, 46, 52, 38, 26, 32, 41,
50, 36, 17, 19, 29, 10, 13, 21,
56, 45, 25, 31, 35, 16, 9, 12,
44, 24, 15, 8, 23, 7, 6, 5};
T log2_64 (T value) {
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
return tab64[((T)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
}
// https://stackoverflow.com/a/101613/6699433
T ipow(T base, T exp) {
T result = 1;
for (;;) {
if (exp & 1) result *= base;
exp >>= 1;
if (!exp) break;
base *= base;
}
return result;
}
T f(T n) { return ipow(2,n-1)*n; }
T numberOfOnes(T x) {
if(x==0) return 0;
T p = floor(log2(x));
T a = f(p);
T e = ipow(2,p);
T b = numberOfOnes(x-e);
T c = x - e + 1;
return a+b+c;
}
void test(T u, T v) {
assert(numberOfOnes(u) == v);
}
int main() {
// Sanity checks
test(0,0);
test(1,1);
test(2,2);
test(3,4);
test(4,5);
test(5,7);
test(6,9);
// Test case provided in question
test(1000000000,14846928141);
}
int x1 = 5;
int x2 = 10;
int i=0;
int looper = 0;
unsigned long long ones_count = 0;
for(i=x1; i<=x2; i++){
looper = i;
while(looper){
if(looper & 0x01){
ones_count++;
}
looper >>= 1;
}
}
printf("ones_count is %llu\n", ones_count);
return 0;
OUTPUT: ones_count is 12
Here is a way to count every single bit for every value in between the two values. The shift/mask will be faster than your arithmetic operators most likely, but will still probably time out. You need a clever algorithm like the other answer suggests i think, but heres the stupid brute force way :)
This was my solution to the problem:
** = exponentiation
/ = whole number division
Consider the numbers from 1 to 16:
00001
00010
00011
00100
00101
00110
00111
01000
01001
01010
01011
01100
01101
01110
01111
10000
If you pay attention to each column, you'll notice a pattern. The bit at column index i (0,1,2 ...) from the right runs through a cycle of length 2**(i+1), that is every 2**(i+1) rows, the pattern in column i repeats itself. Notice also that the first cycle starts at the first occurrence of a 1 in a given column. The number of ones in a pattern is half of the patterns length.
Example:
i pattern
0 10
1 1100
2 11110000
3 1111111100000000
...
So, given the task of summing all ones up to n, we have to keep track of how many times each pattern repeats itself and also if a pattern fails to complete itself.
Solution:
Let x be the biggest exponent of a binary number n and let s be the sum of all ones up to n. Then, for i = (0, 1, 2, ... , x) add (n / 2**(i+1)*(2**i) to s. If the remainder is bigger than 2**i, add 2**i to s, else add the remainder. Then subtract 2**i from n and repeat the process.
Example:
n = 7 -> x = 2
(7 / 2**1)*(2**0) = 3
7 % 2**1 = 1 !> 2**0
s = 1 + 3 (4)
n = n - 2**0 (6)
(6 / 2**2)*(2**1) = 2
6 % 2**2 = 2 !> 2**1
s = s + 2 + 2 (8)
n = n - 2**1 (4)
(4 / 2**3)*(2**2) = 0
4 % 2**3 = 4 !> 2**2
s = s + 4 (12)
n = n - 2**2 (0)
s = 12
Maybe not the best explanation or the most beautiful solution, but it works fine.
In python:
def cnt_bin(n):
bits = n.bit_length()
s = 0
for i in range(bits):
s += (n // 2**(i+1))*2**i
if n % 2**(i+1) > 2**i:
s += 2**i
else:
s += (n % 2**(i+1))
n -= 2**i
return s
Then, for a range [a, b] you just compute cnt_bin(b) - cnt_bin(a-1)
I'm having trouble with this binary search algorithm. Here are explanations of the variables.
value: the number being searched within the array
values[]: the array that is being searched
n: number of elements in the array
high: highest element (by zero indexed position) of portion of the array being searched
low: lowest element (by zero indexed position) the portion of the array being searched
My problem isn't the recursion. The portion of the array being searched centers around "value" and conditions identified below are being met. the problem is that my if statements don't seem to be recognizing that they are. I know the conditions are being met because when I print out values[high], values[middle], and values[low] for each recursion it shows that they are.
int search(int value, int values[], int n, int high, int low)
{
if (n <= 0)
{
return 1;
}
int middle = (high + low) / 2;
///condition #1
if (value == values[middle])
{
return 0;
}
//conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
else if ( values[middle]==values[low] || values[middle]==values[high])
{
return 0;
}
else if (value > values[middle])
{
low = middle;
search(value, values, n, high, low);
}
else if (value < values[middle])
{
high = middle;
search(value, values, n, high, low);
}
return 2;
}
What's wrong here?
Look closely at this code:
else if (value > values[middle])
{
low = middle;
search(value, values, n, high, low);
}
else if (value < values[middle])
{
high = middle;
search(value, values, n, high, low);
}
Notice that in these cases you call the search function recursively, but you don't do anything with the return value. This means that whatever value returned by search is discarded and the code continues on as usually, ultimately returning 2.
To fix this, add in these return statements:
else if (value > values[middle])
{
low = middle;
return search(value, values, n, high, low);
}
else if (value < values[middle])
{
high = middle;
return search(value, values, n, high, low);
}
Generally speaking, if you suspect that an if statement condition isn't firing, it's worth slowly stepping through things with a debugger. Doing so would likely lead you to notice that you were (1) calling the function recursively correctly but (2) returning and discarding the returned value.
There may be other issues with the code here, but this is certainly something that you're going to need to address.
Quoth cb3k
That seemed to make it work...what might the other problems be?
Here's your code with the minimal (necessary, but not sufficient) fix diagnosed by templatetypedef and a test harness.
#include <stdio.h>
static
int search(int value, int values[], int n, int high, int low)
{
if (n <= 0)
{
return 1;
}
int middle = (high + low) / 2;
///condition #1
if (value == values[middle])
{
return 0;
}
// conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
else if (values[middle] == values[low] || values[middle] == values[high])
{
return 0;
}
else if (value > values[middle])
{
low = middle;
return search(value, values, n, high, low);
}
else if (value < values[middle])
{
high = middle;
return search(value, values, n, high, low);
}
return 2;
}
int main(void)
{
int data[15];
for (int i = 0; i < 15; i++)
data[i] = 2 * i + 1;
printf("Data:");
for (int i = 0; i < 15; i++)
printf("%3d", data[i]);
putchar('\n');
for (int i = -1; i < 2 * 15 + 3; i++)
printf("Search for %2d - result %d\n", i, search(i, data, 15, 14, 0));
return 0;
}
Here's the output:
Data: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29
Search for -1 - result 0
Search for 0 - result 0
Search for 1 - result 0
Search for 2 - result 0
Search for 3 - result 0
Search for 4 - result 0
Search for 5 - result 0
Search for 6 - result 0
Search for 7 - result 0
Search for 8 - result 0
Search for 9 - result 0
Search for 10 - result 0
Search for 11 - result 0
Search for 12 - result 0
Search for 13 - result 0
Search for 14 - result 0
Search for 15 - result 0
Search for 16 - result 0
Search for 17 - result 0
Search for 18 - result 0
Search for 19 - result 0
Search for 20 - result 0
Search for 21 - result 0
Search for 22 - result 0
Search for 23 - result 0
Search for 24 - result 0
Search for 25 - result 0
Search for 26 - result 0
Search for 27 - result 0
Search for 28 - result 0
Search for 29 - result 0
Search for 30 - result 0
Search for 31 - result 0
Search for 32 - result 0
It is returning 0 regardless of whether the value sought is present in the array or not. This is incorrect behaviour.
You should take time out to study Programming Pearls by Jon Bentley. It covers a lot the basics of the testing of binary searches in a variety of forms — the test harness shown is a variant on what he describes. Also take the time to read
Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken. Maybe you should take reassurance that lots of other people have got binary search wrong over time. (IIRC, the first versions of binary search were published in the 1950s, but it wasn't until the early 1960s that a correct version was published — and then there's the Extra information from 2006, too.)
When I added a printf() in the block after else if (values[middle] == values[low] || values[middle] == values[high]), it printed on every search that should have failed. Note that the interface makes it hard to spot what's happening — it doesn't report where the element is found, just whether it is found. You can add the debugging and code changes necessary to deal with the residual problems. (Hint: that condition is probably not part of the solution. However, when you do remove it, the code goes into a permanent loop because you don't eliminate the value known not to be in the range from the range that you check recursively.)
This seems to work — note that return 2; is never executed (because the final else if is never false.
#include <stdio.h>
static
int search(int value, int values[], int n, int high, int low)
{
//if (n <= 0)
if (n <= 0 || high < low)
{
return 1;
}
int middle = (high + low) / 2;
///condition #1
if (value == values[middle])
{
return 0;
}
#if 0
// conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
else if (values[middle] == values[low] || values[middle] == values[high])
{
//printf(" (#2 || #3) ");
return 0;
}
#endif
else if (value > values[middle])
{
//low = middle;
low = middle + 1;
return search(value, values, n, high, low);
}
else if (value < values[middle])
{
//high = middle;
high = middle - 1;
return search(value, values, n, high, low);
}
return 2;
}
int main(void)
{
int data[15];
for (int i = 0; i < 15; i++)
data[i] = 2 * i + 1;
printf("Data:");
for (int i = 0; i < 15; i++)
printf("%3d", data[i]);
putchar('\n');
for (int i = -1; i < 2 * 15 + 3; i++)
printf("Search for %2d - result %d\n", i, search(i, data, 15, 14, 0));
return 0;
}
Output:
Data: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29
Search for -1 - result 1
Search for 0 - result 1
Search for 1 - result 0
Search for 2 - result 1
Search for 3 - result 0
Search for 4 - result 1
Search for 5 - result 0
Search for 6 - result 1
Search for 7 - result 0
Search for 8 - result 1
Search for 9 - result 0
Search for 10 - result 1
Search for 11 - result 0
Search for 12 - result 1
Search for 13 - result 0
Search for 14 - result 1
Search for 15 - result 0
Search for 16 - result 1
Search for 17 - result 0
Search for 18 - result 1
Search for 19 - result 0
Search for 20 - result 1
Search for 21 - result 0
Search for 22 - result 1
Search for 23 - result 0
Search for 24 - result 1
Search for 25 - result 0
Search for 26 - result 1
Search for 27 - result 0
Search for 28 - result 1
Search for 29 - result 0
Search for 30 - result 1
Search for 31 - result 1
Search for 32 - result 1
How to check if a int var contains a specific number
I cant find a solution for this. For example: i need to check if the int 457 contains the number 5 somewhere.
Thanks for your help ;)
457 % 10 = 7 *
457 / 10 = 45
45 % 10 = 5 *
45 / 10 = 4
4 % 10 = 4 *
4 / 10 = 0 done
Get it?
Here's a C implementation of the algorithm that my answer implies. It will find any digit in any integer. It is essentially the exact same as Shakti Singh's answer except that it works for negative integers and stops as soon as the digit is found...
const int NUMBER = 457; // This can be any integer
const int DIGIT_TO_FIND = 5; // This can be any digit
int thisNumber = NUMBER >= 0 ? NUMBER : -NUMBER; // ?: => Conditional Operator
int thisDigit;
while (thisNumber != 0)
{
thisDigit = thisNumber % 10; // Always equal to the last digit of thisNumber
thisNumber = thisNumber / 10; // Always equal to thisNumber with the last digit
// chopped off, or 0 if thisNumber is less than 10
if (thisDigit == DIGIT_TO_FIND)
{
printf("%d contains digit %d", NUMBER, DIGIT_TO_FIND);
break;
}
}
Convert it to a string and check if the string contains the character '5'.
int i=457, n=0;
while (i>0)
{
n=i%10;
i=i/10;
if (n == 5)
{
printf("5 is there in the number %d",i);
}
}