Related
I am trying to sort floats with radix. My current algorithm works with unsigned. For example, if I enter values 12, 100, 1 my sorted values are 1, 12, and 100. However, when I use a function to convert floats to ints back to floats after calling the radix sort, my values remain unsorted. They print as they were entered by the user.
I am unsure how to modify my current function to be able to sort floats with radix.
void rs(unsigned int *a, int c) {
int i;
int m = a[0];
int bt = 0;
unsigned int *b = malloc(0 * sizeof(int));
for (i = 0; i < c; i++) {
if (a[i] > m)
m = a[i];
}
while((m>>bt) > 0){
int buck[2] = { 0 };
for (i = 0; i < c; i++) {
buck[(a[i]>>bt)&1]++;
}
for (i = 1; i < 2; i++) {
buck[i] += buck[i-1];
}
for (i = c-1; i >= 0; i--) {
b[--buck[(a[i]>>bt)&1]] = a[i];
}
for (i = 0; i < c; i++) {
a[i] = b[i];
}
bt++;
}
free(b);
}
The function I am using to transform floats to ints to floats is: Radix Sort for Floats
void rfloat(float* arr, size_t size) {
assert(sizeof(unsigned) == sizeof(float) && sizeof(float) == 4);
unsigned* d = malloc(size * sizeof(unsigned));
for (size_t i = 0; i < size; i++) {
// Interpret float as 32-bit unsigned.
d[i] = *(unsigned*) &(arr[i]);
// Flip all except top if top bit is set.
d[i] ^= (((unsigned) (((int) d[i]) >> 31)) >> 1);
// Flip top bit.
d[i] ^= (1u << 31);
}
rs(d, size);
// Inverse transform.
for (size_t i = 0; i < size; i++) {
d[i] ^= (1u << 31);
d[i] ^= (((unsigned) (((int) d[i]) >> 31)) >> 1);
arr[i] = *(float*) &(d[i]);
}
free(d);
}
There's multiple issues.
You use int all over the place where you should be using unsigned (for values) or size_t (for sizes/indices).
You allocate 0 bytes.
(m >> bt) > 0 doesn't work as a stop condition, shifting bits equal or greater than the width is not specified.
After transforming the data types to unsigned the loop boundaries don't work anymore.
I took the liberty of fixing the above and choosing some better variable names:
#include <limits.h>
void rs(unsigned int *a, size_t c) {
size_t i;
unsigned bit = 0;
unsigned *b = malloc(c * sizeof(unsigned));
unsigned m = a[0]; // Max element.
for (i = 0; i < c; i++) {
if (a[i] > m) m = a[i];
}
while (bit < CHAR_BIT*sizeof(m) && (m >> bit)) {
size_t bucket_len[2] = { 0, 0 };
for (i = 0; i < c; i++) bucket_len[(a[i] >> bit) & 1]++;
size_t bucket_end[2] = {bucket_len[0], bucket_len[0] + bucket_len[1]};
for (i = c; i-- > 0; ) {
size_t j = --bucket_end[(a[i] >> bit) & 1];
b[j] = a[i];
}
for (i = 0; i < c; i++) a[i] = b[i];
bit++;
}
free(b);
}
#include <stdio.h>
#include <math.h>
int prime (long n);
long reverse(long n);
int main(void)
{
long n;
long i, j;
puts("Enter n dight number, and we will help you find symmetrical prime number");
scanf("%ld", &n);
for (i = 11; i < (pow(10, n) - 1); i+= 2)
{
if (prime(i))
{
j = reverse(i);
if (i == j)
{
printf("%ld\n", i);
}
}
}
}
int prime (long n) //estimate whether the number n is primer number
{
int status = 0;
int j;
//1 is prime, 0 is not
if (n % 2 == 0 || n == 3)
{
if (n == 2)
status = 1;
if (n == 3)
status = 1;
else
{
n++;
status = 0;
}
}
else
{
j = 3;
while (j <= sqrt(n))
{
if (n % j == 0)
{
status = 0;
break;
}
else
status = 1;
j+= 2;
}
}
return status;
}
long reverse(long n) //reverse a number
{
int i, j, x;
long k, sum;
int digit = 0;
int ar[1000];
while (n > 0)
{
k = n;
n = n / 10;
x = (k - n*10);
digit++;
ar[digit] = x;
}
for (i = 1,j = digit - 1; i <= digit; i++, j--)
{
sum += ar[i] * pow(10, j)
}
return sum;
}
I build a reverse function in order to reverse numbers, for example, 214, to 412.
This function works fine in individual number, for instance, I type reverse(214), it return 412, which is good. But when I combine reverse() function with for loop, this function can not work... it produces some strange number...
so How can I fix this problem?
The reverse function is extremely complicated. The better way to go about it would be:
long reverse (long n)
{
long result = 0;
while (n != 0)
{
result *= 10;
result += n % 10;
n /= 10;
}
return result;
}
I think the problem in your code is that in the following segment
digit++;
ar[digit] = x;
you first increment the position then assign to it, thus leaving ar[0] unintialized.
How can I fix this problem?
You need to initialize sum
long k, sum = 0;
^
See the code from #Armen Tsirunyan for a simpler approach.
I have to print numbers with max N bits where count of bits set to 1 = count of bits set to 0. I ignoring leading zeros. I thinking that this applies only when count of bits is even.
My code:
int power(k) {
return 1 << k;
}
void print_numbers(int n){
n -= (n % 2); // FOR EVEN COUNT OF BITS
int exp = 1; // EXPONENTS WILL BE ODD (2^1, 2^3, 2^5, ...)
while (exp < n) {
int start = power(exp);
int end = power(exp + 1);
int ones = (exp + 1) / 2; // ALLOWED COUNT OF 1
for (int i = start; i < end; i++) {
int bits_count = 0;
for (int j = 0; j <= exp; j++){ // CHECK COUNT OF 1
bits_count += ((i >> j) & 1);
}
if (bits_count == ones){
printf("%d\n", i);
}
}
exp += 2;
}
For N = 12 this function print 637 numbers. Is this solution correct or am i wrong? Any idea for more efficient or better solution?
I came up with this, which is a totally different approach (and perfectible) but works:
#include <stdio.h>
void checker(int number)
{
int c;
int zeros = 0;
int ones = 0;
for (c = 31; c >= 0; c--)
{
if (number >> c & 1)
{
ones++;
}
else if(ones > 0)
{
zeros++;
}
}
if(zeros == ones)
{
printf("%i\n", number);
}
}
int main()
{
int c;
for (c = 4095; c >= 0; c--)
{
checker(c);
}
return 0;
}
Which get me 638 values (including 0)
I tried to convert a negative decimal number into a binary number and this code perfectly works on my computer, but the code doesn't work another computer.
I didn't get how it is possible. What is wrong in my code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void decTobin(int dec, int s)
{
int b[s], i = 0;
while (dec >= 0 && i != s - 1) {
b[i] = dec % 2;
i++;
dec /= 2;
}
int j = i;
printf("%d", dec);
for (j = i - 1; j >= 0; j--) {
if (b[j] == NULL)
b[j] = 0;
printf("%d",b[j]);
}
}
void ndecTobin(int dec, int s)
{
int b[s], i = 0, a[s], decimal, decimalvalue = 0, g;
while (dec >= 0 && i != s-1) {
b[i] = dec % 2;
i++;
dec /= 2;
}
int j = i;
printf("%d",dec);
for (j = i - 1; j >= 0; j--) {
if (b[j] == NULL)
b[j] = 0;
printf("%d",b[j]);
}
printf("\n");
a[s - 1] = dec;
for (j = s - 2; j >= 0; j--) {
a[j] = b[j];
}
for (j = s - 1; j >= 0; j--) {
if (a[j] == 0)
a[j] = 1;
else
a[j] = 0;
printf("%d",a[j]);
}
for (g = 0; g < s; g++) {
decimalvalue = pow(2, g) * a[g];
decimal += decimalvalue;
}
decimal = decimal + 1;
printf("\n%d\n", decimal);
decTobin(decimal, s);
}
int main()
{
int a, b;
printf("enter a number: ");
scanf(" %d", &a);
printf("enter the base: ");
scanf("%d", &b);
ndecTobin(a, b);
}
decimal and int b[s] not initialized.
By not initializing decimal to 0, it might have the value of 0 on a machine one day and quite different results otherwise.
void decTobin(int dec, int s) {
// while loop does not set all `b`,but following for loop uses all `b`
// int b[s], i = 0;
int b[s] = { 0 }; // or int b[s]; memset(b, 0, sizeof b);
int i = 0;
}
void ndecTobin(int dec, int s) {
int b[s], i = 0, a[s], decimal, decimalvalue = 0, g;
decimal = 0;
...
decimal += decimalvalue;
}
Minor points:
1) if (b[j] == NULL) b[j] = 0; is strange. NULL is best used as a pointer, yet code is comparing b[j], an int to a pointer. Further, since NULL typically has the arithmetic value of 0, code looks like if (b[j] == 0) b[j] = 0;.
2) decTobin() is challenging to follow. It certainly is only meant for non-negative dec and s. Candidate simplification:
void decTobin(unsigned number, unsigned width) {
int digit[width];
for (unsigned i = width; i-- > 0; ) {
digit[i] = number % 2;
number /= 2;
}
printf("%u ", number); // assume this is for debug
for (unsigned i = 0; i<width; i++) {
printf("%u", digit[i]);
}
}
It looks like you are just printing the number as a binary representation. If so this version would work.
void print_binary(size_t n) {
/* buffer large enough to hold number to print */
unsigned buf[CHAR_BIT * sizeof n] = {0};
unsigned i = 0;
/* handle special case user calls with n = 0 */
if(n == 0) {
puts("0");
return;
}
while(n) {
buf[i++] = n % 2;
n/= 2;
}
/* print buffer backwards for binary representation */
do {
printf("%u", buf[--i]);
} while(i != 0);
}
If you don't like the buffer, you can also do it using recursion like this:
void using_recursion(size_t n)
{
if (n > 1)
using_recursion(n/2);
printf("%u", n % 2);
}
Yet another way is to print evaluating most significant bits first. This however introduces issue of leading zeros which in code below are skipped.
void print_binary2(size_t n) {
/* do not print leading zeros */
int i = (sizeof(n) * 8)-1;
while(i >= 0) {
if((n >> i) & 1)
break;
--i;
}
for(; i >= 0; --i)
printf("%u", (n >> i) & 1);
}
Different OS/processor combinations may result in C compilers that store various kinds of numeric variables in different numbers of bytes. For instance, when I first learned C (Turbo C on a 80368, DOS 5) an int was two bytes, but now, with gcc on 64-bit Linux, my int is apparently four bytes. You need to include some way to account for the actual byte length of the variable type: unary operator sizeof(foo) (where foo is a type, in your case, int) returns an unsigned integer value you can use to ensure you do the right number of bit shifts.
Please help me to solve this task:
Generate all binary strings of length n with k bits set.(need to write on C)
for example:
n=5
k=3
11100
00111
11010
01011
**01110
11001
10011
**01101
**10110
10101
** can't generate these permutations
Code:
#include <stdio.h>
#define N 10
int main (void)
{
int mas[N]={0},kst,m,n1,z,a,b;
printf("\n\nVvedit` rozmirnist` masyvu: ");
scanf("%d",&kst);
printf("\n\nVvedit` kil`kist` odynyc`: ");
scanf("%d",&n1);
for(m=0;m1;m++)
mas[m]=1;
for(m=0;m<kst;m++)
printf("%d",mas[m]);
printf("\n");
for(m=0;m<n1;m++){
for(z=0;z<(kst-1);z++)
if((mas[z]==1) && (mas[z+1]==0)){
a=mas[z];
mas[z]=mas[z+1];
mas[z+1]=a;
for(b=0;b<kst;b++)
printf("%d",mas[b]);
printf("\n");
}
}
return 0;
}
I have solved this problem earlier! please find my code below! I hope this will help you out.
#include<stdio.h>
int NumberOfBitsSet(int number)
{
int BitsSet = 0;
while(number != 0)
{
if(number & 0x01)
{
BitsSet++;
}
number = number >> 1;
}
return BitsSet;
}
void PrintNumberInBinary(int number, int NumBits)
{
int val;
val = 1 << NumBits; // here val is the maximum possible number of N bits with only MSB set
while(val != 0)
{
if(number & val)
{
printf("1");
}
else
{
printf("0");
}
val = val >> 1;
}
}
int main()
{
int n,k,i;
int max,min;
printf("enter total number of bits and number of bits to be set:\n");
scanf("%d %d", &n, &k);
min = ((1 << k) - 1); //min possible values with k bits set
max = (min << (n-k)); //max possible value with k bits set!
//printf("%d %d", min, max);
for(i=0; i<= max; i++)
{
if(!(i<min))
{
if(NumberOfBitsSet(i) == k)
{
PrintNumberInBinary(i, (n-1));
printf("\n");
}
}
}
return 0;
}
Your code is a mess ;)
Seriously: first rule when solving a task in code is to write clean code, use sensible variable naming etc.
For tasks like this one I would suggest using this.
Now to your sample code: it would not compile and it is hard to read what you are trying to do. Formatted and with some comments:
#include <stdio.h>
#define N 10
int main(void)
{
int mas[N] = {0};
int kst, m, n1, z, a, b;
/* Read width ? */
printf("\n\nVvedit` rozmirnist` masyvu: ");
scanf("%d", &kst);
/* Read number of bit's set? */
printf("\n\nVvedit` kil`kist` odynyc`: ");
scanf("%d", &n1);
/* m1 is not defined, thus the loop give no meaning.
* Guess you are trying to set "bits" integers to 1.
*/
for (m = 0; m1; m++)
mas[m] = 1;
/* This should be in a function as 1. You do it more then once, and
* 2. It makes the code much cleaner and easy to maintain.
*/
for (m = 0; m < kst; m++)
printf("%d", mas[m]);
printf("\n");
for (m = 0; m < n1; m++) {
for (z = 0; z < (kst - 1); z++) {
if ((mas[z] == 1) && (mas[z + 1] == 0)) {
a = mas[z]; /* Same as a = 1; */
mas[z] = mas[z + 1]; /* Same as mas[z] = 0; */
mas[z + 1] = a; /* Same as mas[z + 1] = 1; */
/* Put this into a function. */
for (b = 0; b < kst; b++)
printf("%d", mas[b]);
printf("\n");
}
}
}
return 0;
}
The extensive use of printf when one are not sure of what is going on is a precious tool.
This is not a solution, (it is basically doing the same as your post, but split up), but a sample of something that might be easier to work with. I have also used a char array as C-string instead of integer array. Easier to work with in this situation.
If you want to use integer array I'd suggest you add a print_perm(int *perm, int width) helper function to get it out of the main code.
#include <stdio.h>
#define MAX_WIDTH 10
int get_spec(int *width, int *bits)
{
fprintf(stderr, "Enter width (max %-2d): ", MAX_WIDTH);
scanf("%d", width);
if (*width > MAX_WIDTH) {
fprintf(stderr, "Bad input: %d > %d\n", *width, MAX_WIDTH);
return 1;
}
fprintf(stderr, "Enter set bits (max %-2d): ", *width);
scanf("%d", bits);
if (*bits > MAX_WIDTH) {
fprintf(stderr, "Bad input: %d > %d\n", *bits, MAX_WIDTH);
return 1;
}
return 0;
}
void permutate(int width, int bits)
{
char perm[MAX_WIDTH + 1];
int i, j;
/* Set "bits" */
for (i = 0; i < width; ++i)
perm[i] = i < bits ? '1' : '0';
/* Terminate C string */
perm[i] = '\0';
fprintf(stderr, "\nPermutations:\n");
printf("%s\n", perm);
for (i = 0; i < bits; ++i) {
/* Debug print current perm and outer iteration number */
printf("%*s LOOP(%d) %s\n",
width, "", i, perm
);
for (j = 0; j < (width - 1); ++j) {
if (perm[j] == '1' && perm[j + 1] == '0') {
perm[j] = '0';
perm[j + 1] = '1';
printf("%s j=%d print\n",
perm, j
);
} else {
/* Debug print */
printf("%*s j=%d skip %s\n",
width, "", j, perm
);
}
}
}
}
int main(void)
{
int width, bits;
if (get_spec(&width, &bits))
return 1;
permutate(width, bits);
return 0;
}
If you want to list all of the permutations uniquely without doing "iterate and check", you can do something like this:
# Move peg x up m using s
# x is negative
# m is positive
def move(x, m, s):
for i in range(1, m+1):
s2 = list(s)
s2[x] = 0
s2[x - i] = 1
print(s2)
if x + 1 < 0:
move(x+1, i, s2)
# Print all unique permutations of
# n bits with k ones (and n-k zeros)
def uniqPerms(n, k):
s = [0 for _ in range(n-k)] + [1 for _ in range(k)]
print(s)
move(-k, n-k, s)
if __name__ == '__main__':
from sys import argv
uniqPerms(int(argv[1]), int(argv[2]))
The idea is that you inch the 1's up recursively, so that each movement produces a unique list (since a 1 is now somewhere none was before).
And you said it must be in C:
#include <stdio.h>
#include <stdlib.h>
enum { n = 8 };
struct string
{
char str[n + 1];
};
void move(int x, int m, string s)
{
for (int i = 0; i <= m; ++i)
{
string s2 = s;
s2.str[n + x] = '0';
s2.str[n + x - i] = '1';
printf("%s\n", s2.str);
if (x + 1 < 0)
move(x + 1, i, s2);
}
}
void uniqPerms(int k)
{
string s;
for (int i = 0; i < n - k; ++i)
s.str[i] = '0';
for (int i = n - k; i < n; ++i)
s.str[i] = '1';
s.str[n] = '\0';
printf("%s\n", s.str);
move(-k, n - k, s);
}
int main(int argc, char *argv[])
{
uniqPerms(atoi(argv[1]));
return 0;
}
try this
A[n-1]=0;
func(n-1);
A[n-1]=1;
func(n-1);
//Think simple people but please bear with me i love java
//Assume array A is globally defined
void Binary(int n)
{
if(n<1)
{
System.out.println(A);
}
else
{
A[n-1]=0;
Binary(n-1);
A[n-1]=1;
Binary(n-1);
}
}
here is the recursive solution
#include <iostream>
#include <vector>
using namespace std;
char v[4];
int count = 0;
void printString(){
int i;
for(i = 0; i < 4; i++){
cout << v[i] << " ";
}
cout <<count << endl;
}
void binary(int n){
if(n < 0){
if(count == 2)
printString();
}
else{
v[n] = '0';
binary(n - 1);
v[n] = '1';
count++;
binary(n-1);
count--;
}
}
int main(){
binary(3);
return 0;
}
#include<stdio.h>
int main(){
int n,k,i,j,a[50];
//lets suppose maximum size is 50
printf("Enter the value for n");
scanf("%d",&n);
printf("Enter the value for k");
scanf("%d",&k);
//create an initial bitstring of k 1's and n-k 0's;
for(i=0;i<n;i++){
if(k>0)
a[i]=1;
else
a[i]=0;
k--;
}
for(i=0;i<n;i++){
if(a[i]==1){
for(j=0;j<n;j++){
if(j!=i&&a[j]==0){
a[j]=1;a[i]=0;
for(k=0;k<n;k++){printf("%d\n",a[k]);}
a[i]=1; a[j]=0;
}}}}
return 0;
}
**If Complexity doesn't matter you can use the following code which are done in java. which will provide the desired output in o(2^n).Here I have find all the combination of 0 and 1 for the given n bits in array of size n.In case of K bit is set I have counted the number of 1 presented is equal to k using countBits() funtion.if so I have printed that array.
public class GenerateAllStringOfNBitsWithKBitsSet {
public static int a[] ={0,0,0,0,0};
static int k=3;
public static boolean countBits(){
int y=0;
for(int i=0;i<a.length;i++)
y += a[i] & 1 ;
if(y==k)
return true;
return false;
}
public static void gen(int n)
{
if(n<1)
{
if(countBits())
System.out.println(Arrays.toString(a));
}
else
{
a[n-1]=0;
gen(n-1);
a[n-1]=1;
gen(n-1);
}
}
public static void main(String[] args) {
GenerateAllStringOfNBitsWithKBitsSet.gen(a.length);
}
}