i want to rotate the string one place at a time and print all the rotations
Input : S = "abc"
Output : abc
bca
cab
im trying to concatenate the string and then printing it, but the problem is input string can be of size 10^5 so my array would require to be of 10^10 size.
but im unable to declare that size array, so i wanted a to know if there is a better way to do it
void printRotatedString(char str[])
{
int n = strlen(str);
// Concatenate str with itself
char temp[2*n + 1];
strcpy(temp, str);
strcat(temp, str);
// Print all substrings of size n.
for (int i = 0; i < n; i++)
{
for (int j=0; j != n; j++)
printf("%c",temp[i + j]);
printf("\n");
}
}
i expect it to work even for 10^5 sized strings
You can do it, even without concatenation. But why do you need it? It will be better if you provide an actual problem source.
void printRotatedString(char str[]) {
int n = strlen(str);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
printf("%c", str[(i + j) % n]);
printf("\n");
}
}
We can come up with another solution using prefix sums. Let's calculate array c where c[i] = the number of letters in our string which are even(or another boolean function) from the beginning. We can calculate it easily if we know c[i - 1], c[i] would be c[i - 1] + 1 if i-th letter is even, c[i] = c[i - 1] otherwise.
So let's use the same idea, let's concatenate our string on its own. And then try to check every substring length of our input string. Having prefix sums, we can easily check if the left-hand side has more even elements than the right-hand side.
Here is the solution code:
int c[100500];
int isEven(char c) {
return c % 2 == 0;
}
int solve(char str[]) {
int n = strlen(str);
char temp[2*n + 1];
strcpy(temp, str);
strcat(temp, str);
for (int i = 0; i < n + n; i++) {
c[i + 1] = c[i] + isEven(temp[i]);
}
int counter = 0;
for (int i = 1; i + n <= n + n; ++i) {
int l = i, r = i + n - 1;
int mid = i + n / 2;
int leftSide = c[mid - 1] - c[l - 1];
int rightSide = c[r] - c[mid - 1];
if (leftSide > rightSide) {
++counter;
}
}
return counter;
}
Related
I'm sorry to ask help for a HackerRank problem here, I know it's not really the right place but nobody is answering me on HackerRank. Also, I'm new in C, so don't be to rude please.
Problem's description:
You are given n triangles, specifically, their sides a, b and c. Print them in the same style but sorted by their areas from the smallest one to the largest one. It is guaranteed that all the areas are different.
Link to the problem : https://www.hackerrank.com/challenges/small-triangles-large-triangles/problem
We can only edit the sort_by_area function.
First of all, I didn't calculate the triangles' area, I've just calculated the perimeter of each triangle, because the formula is simpler to read and to execute. Normally, that doesn't change anything for the result since a bigger perimeter means a bigger area. Tell me if I'm wrong.
The problem is that I have unexpected results: there's numbers on a line from my output that I really don't know from where they come. See:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(100 * sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
temp = tr[j].a;
tr[j].a = tr[j + 1].a;
tr[j + 1].a = temp;
temp = tr[j].b;
tr[j].b = tr[j + 1].b;
tr[j + 1].b = temp;
temp = tr[j].c;
tr[j].c = tr[j + 1].c;
tr[j + 1].c = temp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
Input:
3
7 24 25
5 12 13
3 4 5
Output:
0 417 0 // Unexpected results on this line.
3 4 5
5 12 13
Expected output:
3 4 5
5 12 13
7 24 25
It seems that an error occurs from the 7 24 25 triangle, but for me, my code seems to be good.... Can you help to find out what's wrong ? I really want to understand before going to another problem.
The assumption that a greater parameter implies a greater area is incorrect. Why? Imagine an isosceles triangle with a base of 1000 units and a height of 1e-9 units. The area is minuscule, compared to an equilateral triangle with unit length whereas the former has a huge perimeter (~2000 units) compared to the latter (3 units). That's just an (extreme) example to convey the flaw in your assumption.
I'd suggest you roll up your own area function. It's even mentioned on the problem page to use Heron's formula. Since it's just to be used in the comparison, then we don't need the exact area but an indicative area. So something like
double area(triangle const* tr) {
if(tr) {
double semiPerimeter = (tr->a + tr->b + tr->c)/2.0;
return semiPerimeter* (semiPerimeter - tr->a) * (semiPerimeter - tr->b) * (semiPerimeter - tr->c);
} else {
return 0;
}
}
Where we don't really need to calculate the square root since we just need to compare the areas across triangles and comparing the square of areas across triangles should be fine.
After this, it's just a matter of plugging this into whatever you did, after correcting the inner j loop to run only till n-1 (as the other answer has also explained)
void sort_by_area(triangle* tr, int n) {
/**
* Sort an array a of the length n
*/
double areaArr[n];
for(size_t i = 0; i < n; ++i) {
areaArr[i] = area(&tr[i]);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (areaArr[j] > areaArr[j + 1]) {
// Sort in area array.
int temp = areaArr[j];
areaArr[j] = areaArr[j + 1];
areaArr[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
You could directly use qsort too here since the problem doesn't prohibit using standard functions, something like:
int qsortCompare(void const* a, void const* b) {
triangle const* trA = a;
triangle const* trB = b;
if(trA && trB) {
double areaA = area(trA);
double areaB = area(trB);
return (areaA < areaB) ? -1 :
((areaA > areaB)? 1: 0);
}
return 0;
}
void sort_by_area(triangle* tr, int n) {
qsort(tr, n, sizeof(triangle), &qsortCompare);
}
Also, don't be restricted to add functions in the problem solution. The actual driver code only calls sort_by_area() but you can write other functions in the solution and call them from sort_by_area().
The inner loop does not need to run till n, only till n-1
for (int j = 0; j < n - 1; j++)
Because when j == n, then you are comparing with random junk outside of your respective arrays by accessing size[j+1] and tr[j+1].
Also, when swapping, you don't need to copy the structure members one-by-one. You can simply do:
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
Edit: As #CiaPan pointed out:
You have a memory leak. You need to call free() after you are done with using the malloc'd memory.
You are not allocating the right amount of memory. If you are passed more than 100 triangles, your code might behave weirdly or randomly crash.
int *size = malloc(n* sizeof(*size));
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(n* sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
I've been trying to do a Dynamic Programming assignment for university but I had no success so far.
The problem:
Given a DNA string and a list of mutation locations (for exemple, pieces 0 and 2 are mutations), find the longest palindromic sub-sequence that contains the most mutations on it.
Input: a string S with 0 to 2000 chars; an integer N such that 0<=N<=|S| and N positions (numbers from 0 to |S|) of mutations.
Output: an integer representing the size of the longest palindromic sub-sequence containing the maximum number of mutations.
Examples:
Input: CAGACAT 0
Output: 5
Input: GATTACA 1 0
Output: 1
Input: GATTACA 3 0 4 5
Output: 3
Input: TATACTATA 2 4 8
Output: 7
We have to code it in C, but what I really need are ideas, any language or pseudo-code is good to me.
My code to find the LPS (in C)
int find_lps(char *input)
{
int len = strlen(input), i, cur_len;
int c[len][len];
for (i = 0; i < len; i++)
c[i][i] = 1;
for (cur_len = 1; cur_len < len; cur_len++) {
for (i = 0; i < len - cur_len; i++) {
int j = i + cur_len;
if (input[i] == input[j]) {
c[i][j] = c[i + 1][j - 1] + 2;
} else {
c[i][j] = max(c[i + 1][j], c[i][j - 1]);
}
}
}
return c[0][len - 1];
}
What I tried to do for the mutations:
1- Creating an array of places where the LPS is changed. That doesn't work, and really, I have no idea of what to do.
More details about the problem:
In a situation where you have n palindromic subsequences, both of them with the same size of mutations inside, I need the longest of them. Given that you have n palindromic subsequences with X mutations, (we have M mutations), I need the longest palindromic subsequence of X mutations, considering you don't have a palindromic subsequence with M mutations. If you do, then you should choose the other subsequence, even if it's shorter. So, first criteria: most mutations in a palindromic subsequence. If we have the same amount, then the longest of the subsequences.
Any help is appreciated, thank you.
Lets define C[i][j] to store 2 values:
1- The length of the longest palindromic sub-sequence in the sub-string S(i,j) that contains the most mutations in it, and lets denote it by C[i][j].len
2- The number of mutations in the longest palindromic sub-sequence in the sub-string S(i,j) that contains the most mutations in it, and lets denote it by C[i][j].ms
Then the result of the problem would be C[0][|S|-1].len
Note: m[i] = 1 means the character s[i] is a mutation, otherwise m[i] = 0
Here is the full code written in c++:
#include <iostream>
#include <string>
using namespace std;
string s;
int m[2001];
struct Node {
int ms;//number of mutations
int len;
Node() {
ms = len = 0;
}
Node(int v1,int v2) {
ms = v1;
len = v2;
}
};
Node C[2001][2001];
Node getBestNode(Node n1, Node n2) {
if (n1.ms > n2.ms)
return n1;
if (n1.ms < n2.ms)
return n2;
if (n1.len > n2.len)
return n1;
if (n1.len < n2.len)
return n2;
return n1;
}
void init() {
for (int i = 0; i < 2001; i++) {
m[i] = 0;
for (int j = 0; j < 2001; j++) C[i][j] = Node(0,0);
}
}
void solve() {
int len = s.length();
// initializing the ranges of length = 1
for (int i = 0; i < len; i++)
C[i][i] = Node( m[i],1 );
// initializing the ranges of length = 2
for (int i = 0; i < len - 1; i++)
if (s[i] == s[i + 1])
C[i][i + 1] = Node(m[i] + m[i + 1],2);
else if (m[i] || m[i + 1])
C[i][i + 1] = Node(1,1) ;
// for ranges of length >= 3
for (int cur_len = 3; cur_len <= len; cur_len++)
for (int i = 0; i <= len - cur_len; i++) {
int j = i + cur_len - 1;
C[i][j] = getBestNode(C[i + 1][j], C[i][j-1]);
if (s[i] == s[j]) {
Node nn = Node(
C[i + 1][j - 1].ms + m[i] + m[j] ,
C[i + 1][j - 1].len + 2
);
C[i][j] = getBestNode(C[i][j], nn);
}
}
}
int main() {
int n;
cin >> s >> n;
init();//initializing the arrays with zeros
for (int i = 0; i < n; i++) {
int x; cin >> x;
m[x] = 1;
}
solve();
cout << C[0][s.length()-1].len << endl;
return 0;
}
The function getBestNode() is returning the best of 2 solutions by considering the number of mutations then the length of the sub-sequence.
Note: The code can be shorter, but I made it this way for clarity.
I have to make a program that sort strings (with exact length 7 chars) by using radix sort. I already made a function that sort each column separately. My problem is how to make the whole string move, not just one char. It's really problematic for me to see how should it work in C.
I made one array "char strings[3][8]" and "char output[3][8]" to get sorted 3 strings with exact 7 chars in each one. For example sorting these strings:
strcpy(strings[0], "kupbars");
strcpy(strings[1], "daparba");
strcpy(strings[2], "jykaxaw");
In output I get:
dakaaaa
juparbs
kypbxrw
Each column is sorted correctly but chars don't stick together. I tried many ways for 3 hours but nothing works.
My code looks like this:
void countingSort(char a[][8], char b[][8]) {
int c[123];
for (int pos = 6; pos >= 0; pos--) {
for (int i = 0; i < 123; i++)
c[i] = 0;
for (int i = 0; i < 3; i++)
c[(int)a[i][pos]]++;
for (int i = 1; i < 123; i++)
c[i] += c[i - 1];
for (int i = 2; i >= 0; i--) {
b[--c[(int)a[i][pos]]][pos] = a[i][pos];
}
}
}
(There are constants limiting string length etc. because it's easy to change it to variable - I just focused on getting this program work properly.)
Try changing the loop to move an entire string:
for (int i = 2; i >= 0; i--) {
int k = --c[(int)a[i][pos]];
for(int j = 0; j < 8; j++) {
b[k][j] = a[i][j];
}
}
You could do a circular list but it's a little overhead. I propose you to use memmove().
#include <string.h>
void array_move_forward(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][6];
memmove(array[i] + 1, array[i], 6);
array[i][0] = tmp;
}
}
void array_move_rewind(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][0];
memmove(array[i], array[i] + 1, 6);
array[i][6] = tmp;
}
}
A other solution would be to manipulate your string yourself and using a index, that indicate the first letter of your string.
{
char str[7];
int i = 0;
...
int j = i;
for (int k = 0; k < 7; k++) {
char tmp = str[j++ % 7];
}
}
With that you could rotate your string just with i++ or i--.
struct my_string_radix {
char str[7];
int begin;
}
I have the following code:
void sortStrings(char strings[5][32])
{
int i = 0, j = 0, wall = 0;
int min = i;
for (int i = wall; i < 5; i++){
min = i;
for (j = wall; j < 5; j++){
if (strcmp(strings[j], strings[min]) < 0){
min = j;
}
}
swapStrings(strings[min], strings[wall]);
wall++;
}
}
What this code does is sorts a 2d array of strings by alphabetical order, I have tested it and it works correctly, now my question is how could I implement this code WITHOUT using array operations (aka using pointers and pointer operations only).
This is what I have so far and it is crashing when I try to run it so what am I doing wrong?
{
int i = 0, j = 0, wall = 0;
char *p = strings;
int min;
for (i = wall; i < 5; i++){
min = i;
for (j = wall; j < 5; j++){
if (*(p + j) < *(p + min)){
min = j;
}
}
swapStrings(*(p + j),*(p + wall));
wall++;
}
}
Here is the swapStrings method I am using for reference:
void swapStrings(char string1[], char string2[])
{
char temp[32];
strcpy(temp, string1);
strcpy(string1, string2);
strcpy(string2, temp);
}
The expected output is: if I were to enter in 5 strings, lets say they are:
hello
goodbye
how
are
you
It should return:
are
goodbye
hello
how
you
Thank you.
You have two things wrong:
p have to be char** and not char*
Comparing yourself between strings need a loop such:
int t = 0;
while (*(*(p + j)+t) && (*(*(p + j) + t) == *(*(p + min) + t)))
t++;
if (*(*(p + j) + t) < *(*(p + min) + t)) {
min = j;
}
Maybe you want to write your function for compare.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to code the Waterman algorithm in C.
Now when the length of the sequence exceeds 35 the program just lags.
I have no idea where to start looking, tried but got nothing worked out.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Max Function Prototype.
int maxfunction(int, int);
// Prototype of the random Sequences generator Function.
void gen_random(char *, const int);
int main(int argc, char *argv[]) {
// Looping variable and Sequences.
int i = 0, j = 0, k = 0;
char *X, *Y;
int length1, length2;
// Time Variables.
time_t beginning_time, end_time;
// Getting lengths of sequences
printf("Please provide the length of the first Sequence\n");
scanf("%d", &length1);
printf("Please provide the length of the second Sequence\n");
scanf("%d", &length2);
X = (char*)malloc(sizeof(char) * length1);
Y = (char*)malloc(sizeof(char) * length2);
int m = length1 + 1;
int n = length2 + 1;
int L[m][n];
int backtracking[m + n];
gen_random(X, length1);
gen_random(Y, length2);
printf("First Sequence\n");
for (i = 0; i < length1; i++) {
printf("%c\n", X[i]);
}
printf("\nSecond Sequence\n");
for (i = 0; i < length2; i++) {
printf("%c\n", Y[i]);
}
// Time calculation beginning.
beginning_time = clock();
// Main Part--Core of the algorithm.
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
L[i][j] = 0;
} else
if (X[i-1] == Y[j-1]) {
L[i][j] = L[i-1][j-1] + 1;
backtracking[i] = L[i-1][j-1];
} else {
L[i][j] = maxfunction(L[i-1][j], L[i][j-1]);
backtracking[i] = maxfunction(L[i-1][j], L[i][j-1]);
}
}
}
// End time calculation.
end_time = clock();
for (i = 0; i < m; i++) {
printf(" ( ");
for (j = 0; j < n; j++) {
printf("%d ", L[i][j]);
}
printf(")\n");
}
// Printing out the result of backtracking.
printf("\n");
for (k = 0; k < m; k++) {
printf("%d\n", backtracking[k]);
}
printf("Consumed time: %lf", (double)(end_time - beginning_time));
return 0;
}
// Max Function.
int maxfunction(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
// Random Sequence Generator Function.
void gen_random(char *s, const int len) {
int i = 0;
static const char alphanum[] = "ACGT";
for (i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
Since you null terminate the sequence in gen_random with s[len] = 0;, you should allocate 1 more byte for each sequence:
X = malloc(sizeof(*X) * (length1 + 1));
Y = malloc(sizeof(*Y) * (length2 + 1));
But since you define variable length arrays for other variables, you might as well define these as:
char X[length1 + 1], Y[length2 + 1];
Yet something else is causing a crash on my laptop: your nested loops iterate from i = 0 to i <= m, and j = 0 to j <= n. That's one step too many, you index out of bounds into L.
Here is a corrected version:
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
The resulting code executes very quickly, its complexity is O(m*n) in both time and space, but m and n are reasonably small at 35. It runs in less than 50ms for 1000 x 1000.
Whether it implements Smith-Waterman's algorithm correctly is another question.