I have a function counter(string s1, string s2) which takes two strings (both size 4) of numbers as its parameters. s1 is randomly generated while s2 is user-input.
int counter(string s1, string s2){
int count = 0;
int i, j;
if(i != j){
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(s2[i] != s2[j] && s2[j] == s1[i]){
count += 1;
}
}
}
}
return count;
}
What this function does is compare each element of s2 to s1's. If an element of s2 is equal to an element of s1, provided that they do not have the same index or position, count increments by 1. The function, however, encounters problems when s2 contains duplicates. For example, if s1 = 1234 and s2 = 4445, the output should be 1, but my program outputs 3. How should I be able to detect the duplicates in the string?
Forgot to mention this, but s1 (the randomly generated string) has distinct characters.
This would solve the problem you have when the same letter is present in S2 several times.
int counter(string s1, string s2){
int count = 0;
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(i != j){
if(s2[j] == s1[i]){
count += 1;
break; // Break out of inner for-loop
// to avoid counting letters twice
}
}
}
}
return count;
}
However, I'm not sure what you want the program to do in case the same letter is present in S1 several times.
EDIT:
After reading some of the clarifications in the comments, the if-statement should be
if(s2[i] != s2[j] && s2[j] == s1[i]){
like in the original post.
I dare suggest. But I broke my brain your question =)
int counter(string s1, string s2){
int count = 0;
for(int i = 0; i < s1.length(); ++i)
{
string::size_type loc = s2.find(s1[i], 0);
while (loc != string::npos)
{
if(loc != i)
++count;
loc = s2.find(s1[i], loc + 1);
}
}
return count;
}
add your if condition inside the for loop,
int counter(string s1, string s2){
int count = 0;
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(i!=j && s2[j] == s1[i]){
count += 1;
}
}
}
}
return count;
}
You can detect duplicate elements by implementing Levenshtein distance algorithms.
int levenshtein(const char *s, int ls, const char *t, int lt){
int a, b, c;
/* if either string is empty, difference is inserting all chars
* from the other
*/
if (!ls) return lt;
if (!lt) return ls;
/* if last letters are the same, the difference is whatever is
* required to edit the rest of the strings
*/
if (s[ls] == t[ls])
return levenshtein(s, ls - 1, t, lt - 1);
/* else try:
* changing last letter of s to that of t; or
* remove last letter of s; or
* remove last letter of t,
* any of which is 1 edit plus editing the rest of the strings
*/
a = levenshtein(s, ls - 1, t, lt - 1);
b = levenshtein(s, ls, t, lt - 1);
c = levenshtein(s, ls - 1, t, lt );
if (a > b) a = b;
if (a > c) a = c;
return a + 1;}
Related
I recently coded a question, and I have debugged and figured out where the problem is but cannot quite place a finger on it. My program aims to merge groups of sectors if they overlap or are next to each other, but the last section is scrambling the output.
#include <cstdio>
using namespace std;
int main() {
freopen("beachin.txt", "r", stdin);
freopen("beachout.txt", "w", stdout);
int n, u, k, x;
scanf("%d %d %d %d", &n, &u, &k, &x);
int umbrellas[u][2];
for (int i = 0; i < u; i++) {
scanf("%d %d", &umbrellas[i][0], &umbrellas[i][1]);
}
int groups[u][2];
int len = 0;
for (int i = 0; i < u; i++) {
int s1 = umbrellas[i][0];
int e1 = umbrellas[i][1];
int found = false;
for (int a = 0; a < len; a++) {
int s2 = groups[a][0];
int e2 = groups[a][1];
if ((s1 <= e2 && s1 >= s2) || (e1 >= s2 && e1 <= e2) || (s1 <= s2 && e1 >= e2)) {
int start, end;
if (s1 < s2) start = s1;
else start = s2;
if (e1 > e2) end = e1;
else end = e2;
groups[a][0] = start;
groups[a][1] = end;
found = true;
}
}
if (found == false) {
len++;
groups[len][0] = s1;
groups[len][1] = e1;
}
}
int largest = 0; // scramble bit here from for loop
for (int i = 0; i < len; i++) {
int current = groups[i][1]-groups[i][0]+1;
if (current >= largest) largest = current;
}
printf("%d\n", largest);
return 0;
}
My input for this is
7 2 5 2
4 5
5 6
The expected answer is 2, but the output varies between 2 and random long numbers like 1550870207.
Does anyone know why this is happening?
Note: If it's any help, problem statement is here
Pointing out some issues with the code above, many of which you can get reported by using compiler options:
umbrellas[u][2] and groups[u][2]: these are variable length arrays; they're not standard C++.
n, k, and x are declared, read from, but never used later on.
groups is 1) not initialized, 2) filled only for groups[1], so that groups[0] values remain undefined (at if (found == false) block), and 3) accessed both for groups[0] and groups[1] (at bottom for loop).
len is incremented before being used; in the second iteration of the top for loop, the if (found == false) loop is executed twice, so the second time you access groups[2]; that's an out of bounds access.
Check it here. I've modified your code initializing umbrellas at the point of declaration, and using fixed length arrays for umbrellas and groups.
#include <fmt/core.h>
int main() {
int umbrellas[2][2]{ { 4, 5 }, { 5, 6 } };
int groups[2][2]{};
int len{};
for (int i = 0; i < 2; i++) {
fmt::print("*** i = {}\n", i);
int s1 = umbrellas[i][0];
int e1 = umbrellas[i][1];
bool found{ false };
for (int a = 0; a < len; a++) {
int s2 = groups[a][0];
int e2 = groups[a][1];
if ((s1 <= e2 && s1 >= s2) ||
(e1 >= s2 && e1 <= e2) ||
(s1 <= s2 && e1 >= e2)) {
int start{ (s1 < s2) ? s1 : s2 };
int end{ (e1 > e2) ? e1 : e2 };
groups[a][0] = start;
groups[a][1] = end;
found = true;
}
}
if (not found) {
len++;
fmt::print("\tAccessing groups[{}]\n", len);
groups[len][0] = s1;
groups[len][1] = e1;
}
}
int largest = 0; // scramble bit here from for loop
for (int i = 0; i < len; i++) {
int current = groups[i][1] - groups[i][0] + 1;
if (current >= largest) {
largest = current;
}
}
fmt::print("==> largest = {}\n", largest);
}
// Outputs:
//
// *** i = 0
// Accessing groups[1]
// *** i = 1
// Accessing groups[2]
// ==> largest = 2
Given a list of words, a list of single letters (might be repeating), and score of every character.
Return the maximum score of any valid set of words formed by using the given letters (words[i] cannot be used two or more times).
It is not necessary to use all characters in letters and each letter can only be used once. Score of letters 'a', 'b', 'c', ... ,'z' is given by score[0], score[1], ... , score[25] respectively
My approach is
finding score of a word
then can that word be formed or not
and finally, get the result code is given below
class Solution {
public:
// score finder func
int scoreFinder(vector<int>& score , string s){
int ans = 0;
for(int i = 0; i < s.size(); i++){
char ch = s[i];
ans += score[ch -'a'];
}
return ans;
}
// word can be formed or not
bool canFormed(string s , unordered_map<char,int>& myMap){
for(int i = 0; i < s.size(); i++){
if(myMap.count(s[i]) <= 0){
return false;
break;
}else{
myMap[s[i]]--;
}
}
return true;
}
int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score){
// freq Count of letters
/* unordered_map<char,int> map;
for(int i = 0; i < letters.size(); i++){
map[letters[i]]++;
}*/
int result = 0; // final score is stored in it
int idx = 0;
while(idx < words.size()){
// creating new map every time so that check for all possible words combinations
unordered_map<char,int> myMap;
for(int j = 0; j < letters.size(); j++){
myMap[letters[j]] ++; //= map[letters[j]];
}
int tempResult = 0;
for(int i = idx; i < words.size(); i++){
string temp = words[i];
if(canFormed(temp , myMap)){
tempResult += scoreFinder(score , temp);
}
}
result = max(result , tempResult);
idx++;
}
return result;
}
};
Input:
words = ["dog","cat","dad","good"],
letters = ["a","a","c","d","d","d","g","o","o"],
score = [1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0]
Output:
23
but I am getting the wrong output and I am unable to find the error in my code, my output is 33 for this testcase.
There is a minor bug in your code.
In the function canFormed you decrement the counter als in the case where it is 0 already. We could simply add an additional if-statement or rewrite the whole condition.
Please see one possible solution below:
// word can be formed or not
bool canFormed(string s, unordered_map<char, int>& myMap) {
for (int i = 0; i < s.size(); i++) {
if (myMap.count(s[i]) <= 0) {
return false;
}
else {
if (myMap[s[i]] > 0) {
myMap[s[i]]--;
}
else return false;
}
}
return true;
}
Then it should work.
Solved with backtracking in JAVA
public int maxScoreWords(String[] words, char[] letters, int[] score) {
int[] counts = new int[26];
for (char letter : letters) {
counts[letter - 'a']++;
}
return wordHelper(words, counts, score, 0);
}
static int wordHelper(String[] words, int[] counts, int[] score, int index) {
// base case
if (index > words.length - 1) {
return 0;
}
// recursive case - exclude
int excludedSum = wordHelper(words, counts, score, index + 1);
// recursive case - include
int includedSum = 0;
boolean recursionCall = true;
int wordScore = 0;
for (char c : words[index].toCharArray()) {
counts[c - 'a']--;
if (counts[c - 'a'] < 0) {
recursionCall = false;
}
wordScore += score[c - 'a'];
}
if (recursionCall) {
includedSum = wordScore + wordHelper(words, counts, score, index + 1);
}
for (char c : words[index].toCharArray()) {
counts[c - 'a']++;
}
return Math.max(excludedSum, includedSum);
}
This is a leetcode question about " Longest Substring Without Repeating Characters"
and I failed on 987th (It is the final test case)
the reason i fail is because "Time Limit Exceeded"
Can someone give me some advice to fix my code?
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<char> answer;
vector<char> temp;
int len = s.length();
for ( int a = 0; a < len;a++ ){
for( int aa = a; aa < len;aa++ ){
temp.push_back(s[aa]) ;
if ( repeat(temp) ){
temp.pop_back();
changeAnswer(temp,answer);
temp.clear();
aa = len;
}
changeAnswer(temp,answer);
}
}
return answer.size();
}
bool repeat(vector<char> temp){
if ( temp.size() < 2 )
return false;
for ( int a = 0; a < temp.size();a++ )
for ( int aa = a+1; aa < temp.size(); aa++ )
if ( temp[aa] == temp[a] )
return true;
return false;
}
void changeAnswer( vector<char> &temp, vector<char> &answer ){
if ( temp.size()>answer.size() )
answer = temp;
}
};
It looks that you are using a complete brute force approach to solve the question. The time complexity of your solution is O(n^2), if 'n' is the length of the string. In the case of string length being in range 10^5, the time limit will definitely exceed. First, you should try to optimize your code to make it work in O(n) time.
Here is what you can do:
I think hashing would be helpful in this case. You can store the last occurrence of a character in a hashMap or unordered_map and check the current character if it is already there in the map. If so, you need to count only the characters after the last occurrence of this character. To keep track of from where you have to count the characters simply maintain a variable that stores the first index of a substring with unique characters(like 'p' that I have used in the code below).
Here is my implementation of the above:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> mp;
int n = (int)s.length();
if(n == 0){
return 0;
}
int res = 1;
int p = 0;
mp[s[0]] = 0;
for(int i = 1; i < n ; i++){
if(mp.find(s[i]) == mp.end()){
res = max(res, i-p+1);
mp[s[i]] = i;
}
else{
char ch = s[i];
int temp = mp[ch];
if(p <= temp)
p = temp + 1;
res = max(res, i - p + 1);
mp[ch] = i;
}
}
return res;
}
Try this, it should work.
long time lurker, first time poster. I have been working on this problem for the last six hours hours.
Problem:
Implement the following functions. Each function deals with null terminated C-Style strings. You can assume that any char array passed into the functions will contain null terminated data. Place all of the functions in a single file and then create a main() function that tests the functions thoroughly.
Note: You may not use any c-string functions other than strlen().
I am having trouble with the fourth function.
The desired behavior is: This function returns the index in string s where the substring can first be found. For example if s is "Skyscraper" and substring is "ysc" the function would return 2. It should return -1 if the substring does not appear in the string.
prototype:
int findSubstring(char *str, char substring[])
Here's my two starts for function definitions, I'm not really sure if either is going in the right direction, I'm having a lot of trouble keeping the loop iterations in my head, any help would be TREMENDOUSLY appreciated.
int findSubstring(char *str, char substring[]){
int subS = -1, index1 = 0, index2 = 0;
int length1 = (strlen(str) - 1);
int length2 = (strlen(substring) - 1);
if(length1 > length2){
for(int i = 0; i <= length2; i++){
for(int j = 0; j <= length1; j++){
if(*(substring + i) == *(str + j) && *(substring +i) != '\0' ){
i++;
if(index1 == 0){
index1 = i;
}
}
if( *(substring + i) == '\0'){
subS = i + 2;
}
}
}
}
if (length1 < length2){
cout << "Invalid, substring exceeds size of string!" << endl;
}
return subS;
}
int findSubstring(char *str, char substring[]){
int index = -1;
int lengthStr = (strlen(str) - 1);
int lengthSub = (strlen(substring) - 1);
if (lengthStr < lengthSub){
cout << "Invalid input, substring exceeds size of string!" << endl;
}
if( lengthSub == 0){
cout << "";
}
if (lengthStr > lengthSub){
for(int i = 0; i <= lengthSub; i++){
for(int j = 0; j <= lengthStr; j++){
}
return index;
}
//You can replace my str.size() and subString.size() by the size of each c-string.
int stringPointerOperation( string str, string subString )
{
int pos=0;
bool notFound;
for(int i = 0; i < str.size() ; i++)
{
notFound= false;
if(str[i] == subString[0])
{
pos=i;
for(int k = 0 ; k < subString.size() && k < str.size() ; k++,i++)
{
if(subString[k] != str[i] )
{
notFound=true;
break;
}
}
}
}
if(notFound)
return -1;
else
return pos;
}
You are using the wrong strategy for finding a sub-string in a string. The outer for loop needs to iterate over the main string and the inner for loop needs to iterate over the sub-string.
Say you are looking for "de" in "abcdef". The strategy that I find easier to understand and implement is:
Can I find "de" starting from 0 of "abcdef". No, I can't.
Can I find "de" starting from 1 of "abcdef". No, I can't.
Can I find "de" starting from 2 of "abcdef". No, I can't.
Can I find "de" starting from 3 of "abcdef". Yes, I can. Return 3.
Here's a version that works for me.
int findSubstring(char *str, char substring[]){
int i;
int j;
int length1 = strlen(str);
int length2 = strlen(substring);
if(length1 < length2){
std::cout << "Invalid, substring exceeds size of string!" << std::endl;
return -1;
}
for(i = 0; i < length1; i++){
for(j = 0; j < length2; j++){
// The index to use access the element of str
// needs to be offset by i.
if( str[i+j] != substring[j] )
{
break;
}
}
if ( j == length2 )
{
return i;
}
}
return -1;
}
I need to get the unique value from 2 int arrays
Duplicate is allowed
There is just one unique value
like :
int arr1[3]={1,2,3};
int arr2[3]={2,2,3};
and the value i want to get is :
int unique[]={1}
how can i do this?
im already confused in my 'for' and 'if'
this was not homework
i know how to merge 2 arrays and del duplicate values
but i alse need to know which array have the unique value
plz help me :)
and here is some code i did
int arr1[3]={1,2,3}
int arr2[3]={2,2,3}
int arrunique[1];
bool unique = true;
for (int i=0;i!=3;i++)
{
for (int j=0;j!=3;j++)
{
if(arr1[i]==arr2[j])
{
unique=false;
continue;
}
else
{
unique=true;
}
if(unique)
{
arrunique[0]=arr1[i]
break;
}
}
cout << arrunique[0];
Assuming:
You have two arrays of different length,
The arrays are sorted
The arrays can have duplicate values in them
You want to get the list of values that only appear in one of the arrays
including their duplicates if present
You can do (untested):
// Assuming arr1[], arr2[], and lengths as arr1_length
int i = 0,j = 0, k = 0;
int unique[arr1_length + arr2_length];
while(i < arr1_length && j < arr2_length) {
if(arr1[i] == arr2[j]) {
// skip all occurrences of this number in both lists
int temp = arr1[i];
while(i < arr1_length && arr1[i] == temp) i++;
while(j < arr2_length && arr2[j] == temp) j++;
} else if(arr1[i] > arr2[j]) {
// the lower number only occurs in arr2
unique[k++] = arr2[j++];
} else if(arr2[j] > arr1[i]) {
// the lower number only occurs in arr1
unique[k++] = arr1[i++];
}
}
while(i < arr1_length) {
// if there are numbers still to read in arr1, they're all unique
unique[k++] = arr1[i++];
}
while(j < arr2_length) {
// if there are numbers still to read in arr2, they're all unique
unique[k++] = arr2[j++];
}
Some alternatives:
If you don't want the duplicates in the unique array, then you can skip all occurrences of this number in the relevant list when you assign to the unique array.
If you want to record the position instead of the values, then maintain two arrays of "unique positions" (one for each input array) and assign the value of i or j to the corresponding array as appropriate.
If there's only one unique value, change the assignments into the unique array to return.
Depending on your needs, you might also want to look at set_symmetric_difference() function of the standard library. However, its treatment of duplicate values makes its use a bit tricky, to say the least.
#include <stdio.h>
#include <stdlib.h>
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
int arr1[5] = {5,4,6,3,1};
int arr2[3] = {5, 8, 9};
int unique[8];
qsort(arr1,5,sizeof(arr1[0]),cmp);
printf("\n");
qsort(arr2,3,sizeof(arr2[0]),cmp);
//printf("%d", arr1[0]);
int i = 0;
int k = 0;
int j = -1;
while (i < 5 && k < 3)
{
if(arr1[i] < arr2[k])
{
unique[++j] = arr1[i];
i++;
}
else if (arr1[i] > arr2[k])
{
unique[++j] = arr2[k];
k++;
}
else
{
i++;
k++;
}
}
//int len = j;
int t = 0;
if(i == 5)
{
for(t = k; t < 3; t++)
unique[++j] = arr2[t];
}
else
for(t = i; t < 5; t++)
unique[++j] = arr2[t];
for(i = 0; i <= j; i++)
printf("%d ", unique[i]);
return 0;
}
This is my codes,though there is a good answer .
I didn't realize the idea that know which array have the unique value.
I also think that the right answer that you chose didn't , either.
Here is my version of the algorithm for finding identical elements in sorted arrays on Python in C ++, it works in a similar way
def unique_array(array0 : (int), array1 : (int)) -> (int):
index0, index1, buffer = 0, 0, []
while index0 != len(array0) and index1 != len(array1):
if array0[index0] < array1[index1]:
buffer.append(array0[index0])
index0 += 1
elif array0[index0] > array1[index1]:
buffer.append(array1[index1])
index1 += 1
else:
index0 += 1; index1 += 1
buffer.extend(array0[index0 : len(array0)])
buffer.extend(array1[index1 : len(array1)])
return buffer