Does this bubble sort work? - bubble-sort

Data to sort:
410
253
330
124
285
Result after running the function below:
410
330
253
285
124
function SortData()
i as integer
i= numDat.length
j as integer= 0
temp as integer
//Bubble Sort
while(i> 0)
while(j< i- 1)
if(numDat[j] < numDat[j+ 1])
temp= numDat[j+ 1]
numDat[j+ 1]= numDat[j]
numDat[j]= temp
endif
j= j+ 1
endwhile
i= i- 1
endwhile
endfunction
I have been scratching my head for a good time now, if someone could help it would be much appreciated, Thank you.

In bubble sort after each iteration, we need to initialize next iteration to initial values.
while(i> 0)
j = 0
while(j< i- 1)
if(numDat[j] < numDat[j+ 1])
temp= numDat[j+ 1]
numDat[j+ 1]= numDat[j]
numDat[j]= temp
endif
j= j+ 1
endwhile
i= i- 1
endwhile

Related

Generate stepping numbers upto a given number N

A number is called a stepping number if all adjacent digits in the number have an absolute difference of 1.
Examples of stepping numbers :- 0,1,2,3,4,5,6,7,8,9,10,12,21,23,...
I have to generate stepping numbers upto a given number N. The numbers generated should be in order.
I used the simple method of moving over all the numbers upto N and checking if it is stepping number or not. My teacher told me it is brute force and will take more time. Now, I have to optimize my approach.
Any suggestions.
Stepping numbers can be generated using Breadth First Search like approach.
Example to find all the stepping numbers from 0 to N
-> 0 is a stepping Number and it is in the range
so display it.
-> 1 is a Stepping Number, find neighbors of 1 i.e.,
10 and 12 and push them into the queue
How to get 10 and 12?
Here U is 1 and last Digit is also 1
V = 10 + 0 = 10 ( Adding lastDigit - 1 )
V = 10 + 2 = 12 ( Adding lastDigit + 1 )
Then do the same for 10 and 12 this will result into
101, 123, 121 but these Numbers are out of range.
Now any number transformed from 10 and 12 will result
into a number greater than 21 so no need to explore
their neighbors.
-> 2 is a Stepping Number, find neighbors of 2 i.e.
21, 23.
-> generate stepping numbers till N.
The other stepping numbers will be 3, 4, 5, 6, 7, 8, 9.
C++ code to do generate stepping numbers in a given range:
#include<bits/stdc++.h>
using namespace std;
// Prints all stepping numbers reachable from num
// and in range [n, m]
void bfs(int n, int m)
{
// Queue will contain all the stepping Numbers
queue<int> q;
for (int i = 0 ; i <= 9 ; i++)
q.push(i);
while (!q.empty())
{
// Get the front element and pop from the queue
int stepNum = q.front();
q.pop();
// If the Stepping Number is in the range
// [n, m] then display
if (stepNum <= m && stepNum >= n)
cout << stepNum << " ";
// If Stepping Number is 0 or greater than m,
// need to explore the neighbors
if (stepNum == 0 || stepNum > m)
continue;
// Get the last digit of the currently visited
// Stepping Number
int lastDigit = stepNum % 10;
// There can be 2 cases either digit to be
// appended is lastDigit + 1 or lastDigit - 1
int stepNumA = stepNum * 10 + (lastDigit- 1);
int stepNumB = stepNum * 10 + (lastDigit + 1);
// If lastDigit is 0 then only possible digit
// after 0 can be 1 for a Stepping Number
if (lastDigit == 0)
q.push(stepNumB);
//If lastDigit is 9 then only possible
//digit after 9 can be 8 for a Stepping
//Number
else if (lastDigit == 9)
q.push(stepNumA);
else
{
q.push(stepNumA);
q.push(stepNumB);
}
}
}
//Driver program to test above function
int main()
{
int n = 0, m = 99;
// Display Stepping Numbers in the
// range [n,m]
bfs(n,m);
return 0;
}
Visit this link.
The mentioned link has both BFS and DFS approach.
It will provide you with explaination and code in different languages for the above problem.
We also can use simple rules to move to the next stepping number and generate them in order to avoid storing "parents".
C.f. OEIS sequence
#include <iostream>
int next_stepping(int n) {
int left = n / 10;
if (left == 0)
return (n + 1); // 6=>7
int last = n % 10;
int leftlast = left % 10;
if (leftlast - last == 1 & last < 8)
return (n + 2); // 32=>34
int nxt = next_stepping(left);
int nxtlast = nxt % 10;
if (nxtlast == 0)
return (nxt * 10 + 1); // to get 101
return (nxt * 10 + nxtlast - 1); //to get 121
}
int main()
{
int t = 0;
for (int i = 1; i < 126; i++, t = next_stepping(t)) {
std::cout << t << "\t";
if (i % 10 == 0)
std::cout << "\n";
}
}
0 1 2 3 4 5 6 7 8 9
10 12 21 23 32 34 43 45 54 56
65 67 76 78 87 89 98 101 121 123
210 212 232 234 321 323 343 345 432 434
454 456 543 545 565 567 654 656 676 678
765 767 787 789 876 878 898 987 989 1010
1012 1210 1212 1232 1234 2101 2121 2123 2321 2323
2343 2345 3210 3212 3232 3234 3432 3434 3454 3456
4321 4323 4343 4345 4543 4545 4565 4567 5432 5434
5454 5456 5654 5656 5676 5678 6543 6545 6565 6567
6765 6767 6787 6789 7654 7656 7676 7678 7876 7878
7898 8765 8767 8787 8789 8987 8989 9876 9878 9898
10101 10121 10123 12101 12121
def steppingNumbers(self, n, m):
def _solve(v):
if v>m: return 0
ans = 1 if n<=v<=m else 0
last = v%10
if last > 0: ans += _solve(v*10 + last-1)
if last < 9: ans += _solve(v*10 + last+1)
return ans
ans = 0 if n>0 else 1
for i in range(1, 10):
ans += _solve(i)
return ans

Segmentation fault while returning a 2d vector in C++

vector<vector<int> > Solution::prettyPrint(int A)
{
vector<vector<int>>res(2*A-1, std::vector<int>(2*A-1));
int flag=A;
int i, k=0,l=0;
int m=2*A-1, n=2*A-1;
while(k<=m && l<=n)
{
for(i=l; i<2*A-1; i++)
res[k][i]=flag;//1st row
k++;
for(i=k; i<2*A-1; i++)
res[i][n]=flag;//last column
n--;
for(i=n; i>l; i--)
res[m][i]=flag;//last row
m--;
for(i=m; i>k; i--)
res[i][l]=flag;//1st column
l++;
flag--;
}
return res;
}
why does it give segmentation fault error as i have allocated memory for the complete 2d matrix which will be [2A-1][2A-1].
if A=3
output must be like
3 3 3 3 3 \n
3 2 2 2 3 \n
3 2 1 2 3 \n
3 2 2 2 3 \n
3 3 3 3 3 \n
You go out of bounds, since indexing starts from 0 to 2*A-1. Since int m=2*A-1, n=2*A-1; you need to change this:
while(k<=m && l<=n)
to this:
while(k < m && l < n)
Here is your error:
while(k<=m && l<=n)
You should use:
while(k<m && l<n)
Because vector indexes starts from 0 and not from 1.

Big O Notation Confusion (C++)

int f(const std::vector<int>& v) {
int result = 0;
for (int i = 0; i < v.size(); ++i) { O(N)
for (int j = v.size(); j >= 0; j -= 2) { O(N/2)
result += v.at(i) * j;
}
}
return result;
}
The inner for loop is O(N/2), however I am wondering why this is because
For example, if v.size() is 10, then
10 >= 0 ✓
8 >= 0 ✓
6 >= 0 ✓
4 >= 0 ✓
2>= 0 ✓
0 >= 0 ✓
-2 Fails
The inner for loop could be executed 6 times with an input size of 10
What am I missing?
EDIT* I understand that only highest magnitude is taken into consideration. This question was more about coming up with the original O(N/2 + 1)
Complexity gives you a way to assess the magnitude of time it would take an input of certain size to complete, not the accurate time it would perform with.
Therefore, when dealing with complexity, you should only consider the highest magnitude, without constant multipliers:
O(N/2 + 1) = O(N/2) = O(N)
In a comment, you said:
I understand this, but I am just curious as to how O(N/2) is obtained
Take a look at the following table:
Size of vector Number of time the inner loop is executed:
0 1
1 1
2 2
3 2
...
100 51
101 51
...
2x x + 1
2x + 1 x + 1
If you take the constant 1 out of that equation, the inner loop is O(N/2).

C++ - Can not access reverse indexing

Please forgive me if the title is wrong, or, does not explain the problem correctly.
I'm trying to calculate the LU Decomposition of a matrix. Give the matrix M:
M = [1 2 3],
[1 2 3],
[3 3 0]
Now I'm following some code that was written here: Link
It uses j i in order to calculate the lower decomposition. When I try this approach, I keep getting a "Runtime error time: 0 memory: 3276 signal:11"
The thing that I do not understand is the fact that, when I output i, j inside of the 3x3 loop, I got:
i, j =
0 0 1 0 2 0
0 1 1 1 2 1
0 2 1 2 2 2
Then when output the indexes of j,i I get:
j, i =
0 0 0 1 0 2
1 0 1 1 1 2
2 0 2 1 2 2
Which seems right in terms of the order [0][0][0][2].........[2][2] so why can I not access this, inside my vector?
The code that I have written so far is:
void lu_decomposition(const std::vector<std::vector<double> > &vals)
{
std::vector<std::vector<double> > lower(3);
for(unsigned i=0; (i < 3); i++)
{
lower[i].resize(3);
for(unsigned j=0; (j < 3); j++)
{
if (j < i)
{
lower[j][i] = 0; // This is ok
}else{
lower[j][i] = vals[j][i]; // This is the runtime error
}
}
std::cout << std::endl;
}
}
The code is also visible on ideone
Let's concentrate on these lines:
lower[i].resize(3);
//...
lower[j][i] = vals[j][i];
Is the problem clear now? You're resizing lower[i], but then you're accessing lower[j] even for j > i, which has not been resized yet. If you need to access the matrix in this fashion, you'll have to preallocate it beforehand. That means to drop the resize call and instead initialise the variable like this:
std::vector<std::vector<double> > lower(3, std::vector<double>(3));

Sum of submatrices of bigger matrix

I have a big matrix as input, and I have the size of a smaller matrix. I have to compute the sum of all possible smaller matrices which can be formed out of the bigger matrix.
Example.
Input matrix size: 4 × 4
Matrix:
1 2 3 4
5 6 7 8
9 9 0 0
0 0 9 9
Input smaller matrix size: 3 × 3 (not necessarily a square)
Smaller matrices possible:
1 2 3
5 6 7
9 9 0
5 6 7
9 9 0
0 0 9
2 3 4
6 7 8
9 0 0
6 7 8
9 0 0
0 9 9
Their sum, final output
14 18 22
29 22 15
18 18 18
I did this:
int** matrix_sum(int **M, int n, int r, int c)
{
int **res = new int*[r];
for(int i=0 ; i<r ; i++) {
res[i] = new int[c];
memset(res[i], 0, sizeof(int)*c);
}
for(int i=0 ; i<=n-r ; i++)
for(int j=0 ; j<=n-c ; j++)
for(int k=i ; k<i+r ; k++)
for(int l=j ; l<j+c ; l++)
res[k-i][l-j] += M[k][l];
return res;
}
I guess this is too slow, can anyone please suggest a faster way?
Your current algorithm is O((m - p) * (n - q) * p * q). The worst case is when p = m / 2 and q = n / 2.
The algorithm I'm going to describe will be O(m * n + p * q), which will be O(m * n) regardless of p and q.
The algorithm consists of 2 steps.
Let the input matrix A's size be m x n and the size of the window matrix being p x q.
First, you will create a precomputed matrix B of the same size as the input matrix. Each element of the precomputed matrix B contains the sum of all the elements in the sub-matrix, whose top-left element is at coordinate (1, 1) of the original matrix, and the bottom-right element is at the same coordinate as the element that we are computing.
B[i, j] = Sum[k = 1..i, l = 1..j]( A[k, l] ) for all 1 <= i <= m, 1 <= j <= n
This can be done in O(m * n), by using this relation to compute each element in O(1):
B[i, j] = B[i - 1, j] + Sum[k = 1..j-1]( A[i, k] ) + A[j] for all 2 <= i <= m, 1 <= j <= n
B[i - 1, j], which is everything of the sub-matrix we are computing except the current row, has been computed previously. You keep a prefix sum of the current row, so that you can use it to quickly compute the sum of the current row.
This is another way to compute B[i, j] in O(1), using the property of the 2D prefix sum:
B[i, j] = B[i - 1, j] + B[i, j - 1] - B[i - 1, j - 1] + A[j] for all 1 <= i <= m, 1 <= j <= n and invalid entry = 0
Then, the second step is to compute the result matrix S whose size is p x q. If you make some observation, S[i, j] is the sum of all elements in the matrix size (m - p + 1) * (n - q + 1), whose top-left coordinate is (i, j) and bottom-right is (i + m - p + 1, j + n - q + 1).
Using the precomputed matrix B, you can compute the sum of any sub-matrix in O(1). Apply this to compute the result matrix S:
SubMatrixSum(top-left = (x1, y1), bottom-right = (x2, y2))
= B[x2, y2] - B[x1 - 1, y2] - B[x2, y1 - 1] + B[x1 - 1, y1 - 1]
Therefore, the complexity of the second step will be O(p * q).
The final complexity is as mentioned above, O(m * n), since p <= m and q <= n.