I was trying to run it, no matter what i insert into the queue and what the quantity of numbers inserted, it just does not display the circular queue.
These are some points over which i want a clarification and/or correction, would appreciate a response.
in the below code, in the function Insert_in_Cqueue(), towards the end, there is a statement 'rear++; Cqueue[rear] = ele;' , Does rear++ signify that we are moving forward towards the front from the rear, as that is how we insert in a circular queue?
in the function Del_from_Cqueue(), towards the end, there is a statement 'front++', all that it implies is that by incrementing 'front', we just lose track of the element concerned in that particular run of the function del_from_cqueue(), essentially implying that we have deleted the element which we wished to?
The code :
#include<iostream>
#include<conio.h>
#include<process.h>
using namespace std;
int Insert_in_CQueue(int[], int);
void Display(int[], int, int);
int Del_from_CQueue(int CQueue[]);
void main()
{
const int size = 7;
int CQueue[size];
int Item, res, ch, front = -1, rear = -1;
do
{
cout << "\t\t\t Circular Queue Menu\n";
cout << "\t 1. Insert\n";
cout << "\t 2. Delete\n";
cout << "\t 3. Display\n";
cout << "\t 4. Exit\n";
cout << "\n Enter your choice(1-4)";
cin >> ch;
switch (ch)
{
case 1: cout << "\t\t You have selected the option to 'Insert' in the Queue. ";
cout << "\n Enter item for insertion ";
cin >> Item;
res = Insert_in_CQueue(CQueue, Item);
if (res == -1)
{
cout << "\n Overflow encountered";
}
else
{
cout << "\n Now the circular Queue is : ";
Display(CQueue, front, rear);
}
break;
case 2: Item = Del_from_CQueue(CQueue);
cout << "\n Element deleted is : " << Item << endl;
Display(CQueue, front, rear);
break;
case 3: Display(CQueue, front, rear);
break;
case 4: break;
default: cout << "\n Valid choices are 1,2,3,4 only ";
break;
}
} while (ch != 4);
_getch();
return;
}
int Insert_in_CQueue(int CQueue[], int ele)
{
int front = -1, rear = -1;
const int size = 7;
if ((front == 0 && rear == (size - 1)) || (front == rear + 1)) //the
second condition, as it is a circular queue, no end
{
return -1;
}
else if (rear == -1)
{
front = rear = 0;
}
else if (rear == size - 1)
{
rear = 0;
}
else
rear++;
CQueue[rear] = ele;
return 0;
}
void Display(int CQueue[], int front, int rear)
{
int i = 0;
const int size = 50;
cout << "\n Circular Queue is : \n" << "(Front shown as >>>, Rear as <<<
AND Free space as->\n";
if (front == -1)
return;
if (rear >= front)
{
for (i = 0; i < front; i++) cout << "-";
cout << ">>>";
for (i = 0; i < rear; i++) cout << CQueue[i] << "<---";
cout << CQueue[rear] << "<<<" << endl;
}
else
{
for (i = 0; i < rear; i++) cout << CQueue[i] << "<---";
cout << CQueue[rear] << "<<<";
for (i = 0; i < front; i++) cout << "-";
cout << ">>>";
for (i = front; i < size; i++) cout << CQueue[i] << "<---";
}
}
int Del_from_CQueue(int CQueue[])
{
int ret;
int front = -1, rear = -1;
const int size = 50;
if (front == -1) return -1;
else
{
ret = CQueue[front];
if (front == rear) front = rear = -1;
else if (front == size - 1)
front=0;
else front++;
}
return ret;
}
The standard way of checking if a circular queue is full is
if((rear+1)%size == front)
Queue is Full.
The standard way of checking if a circular queue is empty is
if(rear==front)
Queue is Empty.
Remember: In a circular queue, the queue is considered full when one space is still empty. This is done to differentiate between condition of empty and full.
You do no simply increment the front and the rear while inserting or deleting the values. The values of front and rear need to be zero when they reach the queue size.
Eg: With a queue size of 7, when front or rear reaches the value of 6, theit next value should be zero and not 7
So while inserting, you should use:
rear=(rear+1)%size;
CQueue[rear] = ele;
And while deleting, you should use:
ret = CQueue[front];
front=(front+1)%size;
Your answer:
Yes ! When circular queue is empty, both the front and the rear are together. As we insert elements in the queue, the rear increases and the front remains constant. Increasing the rear value while inserting does not mean that we are moving towards the front from the rear, but when the queue approaches to be full, the front and the rear come together.
For example: If you run in a circular path from a starting point, you first move away from the starting point, but as you tend to complete the run, you approach the starting line from the back. Same goes with the circular queue.
Related
I'm doing a relatively simple assignment asking us to intake integers and fail gracefully if it hits something that isn't an integer, written in C++. I'm fairly experienced with the language, and I knew it had functionality for checking reading errors in ios::failbit. As a result I'm using cin.fail() to check for errors here, but its running one loop too late--that is, its running the rest of the code first, and not realizing an error happened until the next time it checks the buffer. The obvious solution is to just check twice, but that just causes infinite loops (even if I flush or clear cin.) Is there any way to check more immediately?
Here's my code:
int min = 101; //One higher than the max.
int pile = 0;
int count = 0;
int temp = 0;
int fail;
std::cout << "Input a series of integers between 0 and 100. When you wish to"
" exit, enter -1.\n";
while (true){
std::cin >> temp;
if (std::cin.fail()){
std::cout << "FAILURE: Bad input. It probably wasn't an integer.\n";
std::cout << "Reading will stop.\n";
break;
}
std::cout << "\nTemp is " << temp << "\n";
if (temp > 100 || temp == -1){
break;
}
if (temp < min){
min = temp;
}
pile += temp;
std::cout << "Pile is " << pile << "\n";
count++;
std::cout << "Count " << count << "\n";
}
std::cout << "Your average was: " << (double)pile/count << ".\n";
std::cout << "Your minimum was: " << min << ".\n";
return 0;
}
I came across this question during an interview -
Convert a number source to target in the minimum number of operations.
Allowed Operations
Multiplied by 2.
Addition by 1.
subtraction by 1.
0 < source, target <= 1000.
I tried going the naive recursive route(O(3^n)) ie. subtract 1, add 1 and multiply by 2 at each level to try and find a solution that I could extend to Dynamic Programming but couldnt because of an infinite loop.
//Naive approach Via Recursion
int minMoves(int source, int target){
if(source <1 || source > target){
return -1;
}
int moves =0;
// Potential infinite loop - consider 3,6-> 2,6- >1,6->(0,6)x (2,6)->1,6->(0,6)x (1,6)->(0,6)x (2,6)->1,6..
int movesLeft = minMoves(source -1, target) ==-1? Integer.MAX_VALUE:minMoves(source -1, target);
int movesRight = minMoves(source +1, target) ==-1? Integer.MAX_VALUE:minMoves(source +1, target);
int moves2X = minMoves(2*source, target) ==-1? Integer.MAX_VALUE:minMoves(2*source, target);
moves = 1+ Math.min(Math.min(movesRight,movesLeft), moves2X);
return moves;
}
Any ideas on how I can tweak my solution? Or possibly a better way to solve it?
If you think about your solution like a graph traversal, where each node is an intermediate value you can produce, your recursive solution is like a depth first search (DFS). You'll have to fully expand until you've tried all solutions from that "branch" of the search space before you can proceed anywhere else. If you have an infinite loop, this means it will never terminate even if a shorter path exists, and even if you don't have an infinite loop, you still have to search the rest of the solution space to make sure its optimal.
Instead, consider an approach similar to breadth first search (BFS). You expand outward uniformly, and will never search a path longer than the optimal solution. Just use FIFO queue to schedule which node to access next. This is the approach I've taken with my solver.
from queue import Queue
def solve(source, target):
queue = Queue()
path = [source]
queue.put(path)
while source != target:
queue.put(path + [source * 2])
queue.put(path + [source + 1])
queue.put(path + [source - 1])
path = queue.get()
source = path[-1]
return path
if __name__ == "__main__":
print(solve(4,79))
One way in which you can speed up(and possibly fix) this code, while maintaining the recursive implementation, is to use memoization.
The issue here is that you are recalculating the same value many times. Instead you can use a map to store the results that you already calculated, and reuse them when you need it again.
This problem can be solved constructively. First, the easy cases. If s=t, the answer is 0. If s > t, the answer is s-t because subtraction by 1 is the only operation that lowers s, and the other two can only increase the number of subtractions required.
Now let's assume s < t. Since s>0 is given, doubling will always be the fastest way to increase (if s is 1, it's tied with incrementing). So if the challenge was to make s >= t, the answer would always be the number of doublings required to do that. This procedure may overshoot t, but the first doubling greater than t and the last doubling not greater than t must be within a factor of 2 of t.
Let's look at the effect of when we do an addition or subtraction. First, look only at addition:
(((s*2) * 2) * 2) + 1 = 8s + 1
vs:
((((s+1)*2) * 2) * 2) = 8s + 8
Putting an addition before n doublings makes the final result 2^n bigger. So consider if s is 3 and t is 8. The last double not bigger than 8 is 6. This is 2 off, so if we put an addition 1 double before the last double, we get what we want: (3+1) * 2. Alternatively we could try overshooting to the first double greater than 8, which is 12. This is 4 off, so we need to put a subtraction two doublings before the last : (3-1)*2*2 = 8
In general if we are x below the target, we need to put a +1 at n doublings before the last if the binary representation of x has a 1 at the nth place.
Similarly, if we are x above the target, we do likewise with -1's.
This procedure won't help for the 1's in x's binary representation that are at a position more than the number of doublings there are. For example, if s = 100, t=207, there is only 1 doubling to do, but x is 7, which is 111. We can knock out the middle one by doing an addition first, the rest we have to do one by one (s+1)*2 + 1 + 1 + 1 + 1 + 1.
Here is an implementation that has a debug flag that also outputs the list of operations when the flag is defined. The run time is O(log(t)):
#include <iostream>
#include <string>
#include <sstream>
#define DEBUG_INFO
int MinMoves(int s, int t)
{
int ans = 0;
if (t <= s)
{
return s - t; //Only subtraction will help
}
int firstDoubleGreater = s;
int lastDoubleNotGreater = s;
int nDouble = 0;
while(firstDoubleGreater <= t)
{
nDouble++;
lastDoubleNotGreater = firstDoubleGreater;
firstDoubleGreater *= 2;
}
int d1 = t - lastDoubleNotGreater;
int d2 = firstDoubleGreater - t;
if (d1 == 0)
return nDouble -1;
int strat1 = nDouble -1; //Double and increment
int strat2 = nDouble; //Double and decrement
#ifdef DEBUG_INFO
std::cout << "nDouble: " << nDouble << "\n";
std::stringstream s1Ops;
std::stringstream s2Ops;
int s1Tmp = s;
int s2Tmp = s;
#endif
int mask = 1<<strat1;
for(int pos = 0; pos < nDouble-1; pos++)
{
#ifdef DEBUG_INFO
if (d1 & mask)
{
s1Ops << s1Tmp << "+1=" << s1Tmp+1 << "\n" << s1Tmp+1 << "*2= " << (s1Tmp+1)*2 << "\n";
s1Tmp = (s1Tmp + 1) * 2;
}
else
{
s1Ops << s1Tmp << "*2= " << s1Tmp*2 << "\n";
s1Tmp = s1Tmp*2;
}
#endif
if(d1 & mask)
strat1++;
d1 = d1 & ~mask;
mask = mask >> 1;
}
strat1 += d1;
#ifdef DEBUG_INFO
if (d1 != 0)
s1Ops << s1Tmp << " +1 " << d1 << " times = " << s1Tmp + d1 << "\n";
#endif
mask = 1<<strat2;
for(int pos = 0; pos < nDouble; pos++)
{
#ifdef DEBUG_INFO
if (d2 & mask)
{
s2Ops << s2Tmp << "-1=" << s2Tmp-1 << "\n" << s2Tmp-1 << "*2= " << (s2Tmp-1)*2 << "\n";
s2Tmp = (s2Tmp-1)*2;
}
else
{
s2Ops << s2Tmp << "*2= " << s2Tmp*2 << "\n";
s2Tmp = s2Tmp*2;
}
#endif
if(d2 & mask)
strat2++;
d2 = d2 & ~mask;
mask = mask >> 1;
}
strat2 += d2;
#ifdef DEBUG_INFO
if (d2 != 0)
s2Ops << s2Tmp << " -1 " << d2 << " times = " << s2Tmp - d2 << "\n";
std::cout << "Strat1: " << strat1 << "\n";
std::cout << s1Ops.str() << "\n";
std::cout << "\n\nStrat2: " << strat2 << "\n";
std::cout << s2Ops.str() << "\n";
#endif
if (strat1 < strat2)
{
return strat1;
}
else
{
std::cout << "Strat2\n";
return strat2;
}
}
int main()
{
int s = 25;
int t = 193;
std::cout << "s = " << s << " t = " << t << "\n";
std::cout << MinMoves(s, t) << std::endl;
}
Short BFS algorithm. It finds the shortest path in graph where every vertex x is connected to x + 1, x - 1 and x * 2; O(n)
#include <bits/stdc++.h>
using namespace std;
const int _MAX_DIS = 2020;
const int _MIN_DIS = 0;
int minMoves(int begin, int end){
queue<int> Q;
int dis[_MAX_DIS];
fill(dis, dis + _MAX_DIS, -1);
dis[begin] = 0;
Q.push(begin);
while(!Q.empty()){
int v = Q.front(); Q.pop();
int tab[] = {v + 1, v - 1, v * 2};
for(int i = 0; i < 3; i++){
int w = tab[i];
if(_MIN_DIS <= w && w <= _MAX_DIS && dis[w] == -1){
Q.push(w);
dis[w] = dis[v] + 1;
}
}
}
return dis[end];
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout << minMoves(1, 1000);
return 0;
}
I have two strings, say str1 and str2. I need to convert the first one to the second one while making the least number of edits. This is what is called as Edit Distance. Suppose we need to convert Sunday to Saturday. The first letter is the same, and the last three are the same as well, so it boils down to converting un to atur. This can be done in 3 steps - Replace 'n' with 'r', insert 't', insert 'a'. That gives the edit distance as 3. Following is the program to find out the edit distance -
// A Dynamic Programming based C++ program to find minimum
// number operations to convert str1 to str2
#include<bits/stdc++.h>
using namespace std;
// Utility function to find minimum of three numbers
int min(int x, int y, int z)
{
return min(min(x, y), z);
}
int editDistDP(string str1, string str2, int m, int n)
{
// Create a table to store results of subproblems
int dp[m+1][n+1];
// Fill d[][] in bottom up manner
for (int i=0; i<=m; i++)
{
for (int j=0; j<=n; j++)
{
// If first string is empty, only option is to
// isnert all characters of second string
if (i==0)
dp[i][j] = j; // Min. operations = j
// If second string is empty, only option is to
// remove all characters of second string
else if (j==0)
dp[i][j] = i; // Min. operations = i
// If last characters are same, ignore last char
// and recur for remaining string
else if (str1[i-1] == str2[j-1])
dp[i][j] = dp[i-1][j-1];
// If last character are different, consider all
// possibilities and find minimum
else
dp[i][j] = 1 + min(dp[i][j-1], // Insert
dp[i-1][j], // Remove
dp[i-1][j-1]); // Replace
}
}
return dp[m][n];
}
// Driver program
int main()
{
// your code goes here
string str1 = "sunday";
string str2 = "saturday";
cout << editDistDP(str1, str2, str1.length(), str2.length());
return 0;
}
While this returns the correct result, I also need to output the exact steps of conversion, i.e. something like
Sunday -> Surday -> Sturday -> Saturday.
How do I do the second step?
Once you have created your dp table, you can work your way back rom (m, n) to (0, 0) in the same way as you created the table.
Here's a solution that prints the modifications, but you could also return a vector of modifications.
int editDistDP(string str1, string str2)
{
int m = str1.length();
int n = str2.length();
int dp[m + 1][n + 1];
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0) {
dp[i][j] = j;
} else if (j == 0) {
dp[i][j] = i;
} else if (str1[i-1] == str2[j-1]) {
dp[i][j] = dp[i-1][j-1];
} else {
dp[i][j] = 1 + min3(dp[i][j - 1],
dp[i - 1][j],
dp[i - 1][j - 1]);
}
}
}
i = m; j = n;
while (i && j) {
if (i == 0) {
cout << "insert " << str2[j - 1] << endl;
j--;
} else if (j == 0) {
cout << "remove " << str1[i - 1] << endl;
i--;
} else if (str1[i - 1] == str2[j - 1]) {
i--; j--;
} else {
int k = imin3(dp[i][j - 1],
dp[i - 1][j],
dp[i - 1][j - 1]);
if (k == 2) {
cout << "replace " << str1[i - 1]
<< " with " << str2[j - 1] << endl;
i--; j--;
} else if (k == 1) {
cout << "remove " << str1[i - 1] << endl;
i--;
} else {
cout << "insert " << str2[j - 1] << endl;
j--;
}
}
}
return dp[m][n];
}
Here, imin3 is a function that returns the index 0, 1 or 2 of the minimum element in the list.
so my program is supposed to use one 5 sized array to store inputted integers. If it's a duplicated integer it would not be stored into the array.
The problem here is there would be 0's in my array indefinitely since i initialized the size to 5. I need to output only the unique numbers how would i do so?
One thing i noticed was that without my unsigned int position; whenever i enter a duplicate integer it would skip the index;
e.g. array[0] = 10, array[1] = 10 // duplicate, array[2] = 20 // inputted 20, this should've been stored into array[1] but it doesn't.
So i had the position to only increment whenever it's not a duplicate to make sure it's not skipping over the index when a duplicate is entered.
And was there anything i could've done or do a different approach to get my result?
Code:
#include <iostream>
#include <iomanip>
#include <array>
using namespace std;
const unsigned int MIN_VALUE = 10;
const unsigned int MAX_VALUE = 100;
const size_t arraySize = 5;
array <int, arraySize> numberArray = {};
template<size_t size>
bool isDuplicate(array<int, size> array, int value)
{
for (unsigned int i = 0; i < array.size(); i++)
{
if (value == array[i])
{
return true;
}
}
return false;
}
int main()
{
unsigned int input;
unsigned int position = 0;
for (unsigned int i = 0; i < arraySize; i++)
{
cout << "Enter # " << (i + 1) << " : ";
cin >> input;
if (input < MIN_VALUE || input > MAX_VALUE)
{
cout << "The number entered is not in valid range of 10 to 100" << endl;
--i;
}
else if (!isDuplicate(numberArray, input))
{
numberArray[position] = input;
position++;
cout << "The number: " << input << " is unique\n" << endl;
}
}
}
Thanks!
The only missing part in your code is an additional block below your else if block:
else {
cout << "The number: " << input << " is not unique\n" << endl;
--i;
}
where you would decrease your position when the value is a duplicate, and warn the user about it.
If I had to update your program while keeping the most of your code I would write:
#include <iostream>
#include <iomanip>
#include <array>
using namespace std;
const unsigned int MIN_VALUE = 10;
const unsigned int MAX_VALUE = 100;
const size_t arraySize = 5;
// Initialize all array values to 0 (see std::array documentation)
array <int, arraySize> numberArray = {0};
template<size_t size>
bool isDuplicate(array<int, size> arr, int val)
{
bool ret = false;
// Do not waste time with invalid values
if (val < MIN_VALUE || val > MAX_VALUE)
return ret;
// Using size_t to express size
size_t pos = 0;
// Loop until reaching the end OR a not yet set array value
while ( pos < arr.size() && arr[pos]){
if (arr[pos] == val) {
// Found!
ret = true;
break;
}
++pos;
}
return ret;
}
int main()
{
unsigned int input = 0;
size_t position = 0;
while (position < numberArray.size()) {
cout << "Enter # " << (position + 1) << " : ";
cin >> input;
if (input < MIN_VALUE || input > MAX_VALUE) {
cout << "The number entered is not in valid range of 10 to 100" << endl;
} else if (!isDuplicate(numberArray, input)) {
numberArray[position] = input;
// Pre-increment operator is more efficient, see doc.
++position;
cout << "The number: " << input << " is unique\n" << endl;
} else {
cout << "The number: " << input << " is not unique\n" << endl;
}
}
}
It looks like an exercise with a really weird specification. It should be better explained so as to give you a more relevant real-life solution. ;)
Hope this helps.
I just faced an interview in TCS , My last question was to write an algorithm to find how many characters need to be added in a string to make it a palindrome. I started out, but wasnt able to complete. what would be a way to find that?
String palindrome = "helllllll";
char [] chars = palindrome.toCharArray();
for (int i = 0; i < chars.length; i++) {
int j = 0;
for (; j < chars.length - i; j++) {
if (chars[i+j] != chars [chars.length - 1-j])
break;
}
if (j == chars.length - i) {
System.out.println (i);
break;
}
}
As what Niklas said:
Find the leftmost character in the right half of the string that is a potential "mirror point" of a palindrome. It induces the solution. Also consider even-length palindromes
So as an example code that explains your question, this performs a palindrome test and then print it out in reverse without characters like '!', ', or '?'
And i have marked out the process that answers your question with a caption:
#include<iostream>
#include<string>
using namespace std;
int main()
{
//Variables and arrays
int const index = 30;
char Phrase[index];
char Reverse[index];
char* Palindrome = Reverse;
int i, j;
cout << "Please enter a sentence to be tested as a palindrome: ";
cin.getline(Phrase, 30);
int length = strlen(Phrase);
bool test = true;
for(i = 0, j = length-1; i < j; i++, j--) //Loops from zero to half of the string
{
if(test) // if it is a palindrome so far
{
while(!isalpha(Phrase[i]) && i < j) { i++; }
while(!isalpha(Phrase[j]) && i < j) { j--; }
if(Phrase[i] != Phrase[j]) //Check if the characters match
{
test = false;
}
}
else
{
break;
}
}
if(test)
{
cout << endl << "Phrase/Word is a Palindrome." << endl << endl;
for(j = strlen(Phrase) - 1; j >= 0; Palindrome++, j--)
{
*Palindrome = Phrase[j];
}
cout << "The phrase and reverse statement is: " << Reverse << endl << endl;
}
else
{
cout << endl << "Phrase/Word is not a Palindrome." << endl << endl;
}
system("Pause");
return 0;
}