Output in the memo field - formatting

void __fastcall TForm1::Step(int _Sum, int _Num, int _Val)
{
if (_Sum <= 0 || _Num <= 0 || _Sum < _Val) return;
if (_Num == 1)
{
data[theK - 1] = _Sum;
Memo1->Lines->Add("{");
for (int i = 0; i < theK; ++i)
Memo1->Lines->Add(data[i]);
sc++;
Memo1->Lines->Add("}");
Memo1->Lines->Add("\n");
Label4->Caption = sc;
return;
}
for (int i = _Val; i < _Sum; ++i)
{
data[theK - _Num] = i;
Step(_Sum - i, _Num - 1, i);
}
}
I have output like this:
1 2 3 4 5 6 7 8 9 10
11 12
But I need output like:
1,2,3,4 5,6,7,8 9,10,11,12
How to do it in C++ Builder? I have Memo1 or ListBox. I need formatting output.

I usually build a UnicodeString for each line of output like so:
UnicodeString Str;
for (int I =0; I<5;i++)
{
Str += IntToStr(I)+","
};
Str.SetLength(Str.Length -1); // trim off last comma
Memo1->Add(Str);

Related

Can't stop while loop which has scanf inside

#include <stdio.h>
int main() {
int test,i = 0,a = NULL;
int max2 = 0;
int n;
int max = -1000000, min = 1000000;
while (scanf("%d", &n) == 1 && max2 < 50)
{
if(n < min) { min = n; }
if(n > max) { max = n; }
max2++;
}
printf("%d",min+max);
return 0;
}
Input should be like this "1 5 8 9 10", I don't know how many numbers would be entered so I have to use the while loop.
Try using do while to put the scanf inside the loop.
#include <stdio.h>
int main() {
int test,i = 0,a = NULL;
int max2 = 0;
int n;
int max = -1000000, min = 1000000;
do{
scanf("%d", &n);
if(n < min) { min = n; }
if(n > max) { max = n; }
max2++;
}while ( n == 1 && max2 < 50)
printf("%d",min+max);
return 0;
}

Bubble sort Descending and Ascending in C won't sort

I'm giving a user choices to whether sort the elements in ascending or descending order. I know my code can sorts the elements right but somewhere in main I think I'm making mistake in calling my function to print the ascending/descending element in their proper order. Or do I have to have another if statement like I have in the bubble_sort function? I need to make it so the Main function prints the final results to the user. Here's the output I'm getting:
Enter number of elements
3
Enter 3 integers
43
7
90
Enter sort order
Please enter A for ascending or D for descending order
d
Sorted list in descending order:
43
7
90
#include <stdio.h>
void bubble_sort(long [], char n);
int main()
{
long array[100], n, c;
printf("Enter number of elements\n");
scanf("%ld", &n);
printf("Enter %ld integers\n", n);
for (c = 0; c < n; c++)
scanf("%ld", &array[c]);
printf("Enter sort order\n");
fflush(stdin);
printf("Please enter A for ascending or D for descending order\n");
scanf("%ld", &n);
bubble_sort(array, n);
printf("Sorted list in descending order:\n");
for ( c = 0 ; c < n ; c++ )
{
printf("%ld\n", array[c]);
}
fflush(stdin);
getchar();
return 0;
}
void bubble_sort(long list[], char n)
{
long c, d, temp;
if(n=='a' || n=='A')
{
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (list[d] > list[d+1])
{
temp = list[d];
list[d] = list[d+1];
list[d+1] = temp;
}
}
}
}
if(n=='d' || n=='D')
{
long c, d, temp;
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d > n - c - 1; d++)
{
if (list[d] < list[d+1])
{/* Swapping */
temp = list[d];
list[d] = list[d+1];
list[d+1] = temp;
}
}
}
}
}
EDIT: Here I added a swap function just so the ascending/descending logic is more efficient. But I seem to mixed up use of the variables which I think is a big problem. Would anyone point out and help me understand where and why I'd need to use those variables? Thanks much!
#include <stdio.h>
void bubble_sort(int list[], int n, char c);
void swap(int x, int y, int array[]);
int main()
{
int array[100], j, i;
char c;
printf("Enter number of elements\n");
scanf("%d", &j);
printf("Enter %d integers\n", j);
for (i = 0; i < j; i++)
scanf("%d", &array[i]);
printf("Please enter A for ascending or D for descending order\n");
scanf("%s", &c);
bubble_sort(array, j, i);
printf("Sorted list in descending order:\n");
for (i = 0 ; i < j ; i++ )
{
printf("%d\n", array[i]);
}
getchar();
return 0;
}
void bubble_sort(int list[], int n, char c)
{
int i, j;
if(c=='a' || c=='A'){
for (i = 0; i < (n - 1); i++){
for (j = 0; j < (n - i) - 1; j++){
if (list[i] > list[j])
{
swap(i, j, list); }
}
}
}
if(c=='d' || c=='D') {
for (i = 0 ; i < ( n - 1 ); i++) {
for (j = 0 ; j > (n - i) - 1; j++) {
if (list[i] < list[j])
{
swap(i, j, list);
}
}
}
}
}
void swap(int x, int y, int array[])
{
int hold; //temp hold a number
hold = array[x];
array[x] = array[y];
array[y] = hold;
}
In this statements
printf("Please enter A for ascending or D for descending order\n");
scanf("%ld", &n);
you are overwritting the value stored in n that before these statements denoted the number of the elements in the array. You should declare one more variable of type char and use it for this code snippet.
Also the sort function should be declared as
void bubble_sort(long list[], int n, char c );
where n is the array size and c is either 'A' or 'D'
EDIT: Your new code contains many typos. Try the following
#include <stdio.h>
void swap( int x, int y, int array[] )
{
int hold; //temp hold a number
hold = array[x];
array[x] = array[y];
array[y] = hold;
}
void bubble_sort( int list[], int n, char c )
{
int i, j;
if ( c == 'a' || c == 'A' )
{
for ( i = 0; i < n - 1; i++ )
{
for ( j = 0; j < n - i - 1; j++ )
{
if ( list[j] > list[j+1] )
{
swap( j, j + 1, list);
}
}
}
}
if ( c=='d' || c=='D' )
{
for ( i = 0 ; i < n - 1; i++ )
{
for ( j = 0 ; j < n - i - 1; j++ )
{
if ( list[j] < list[j+1] )
{
swap( j, j + 1, list);
}
}
}
}
}
int main(void)
{
int array[100], j, i;
char c;
printf("Enter number of elements: ");
scanf( "%d", &j);
printf( "Enter %d integers\n", j );
for ( i = 0; i < j; i++ ) scanf( "%d", &array[i] );
printf("Please enter A for ascending or D for descending order: ");
scanf( " %c", &c );
printf( "%c\n", c );
bubble_sort( array, j, c );
printf( "Sorted list in the selected order:\n" );
for ( i = 0; i < j; i++ )
{
printf( "%d ", array[i] );
}
puts( "" );
return 0;
}

Potential Duplicates Detection, with 3 Severity Level

I wanna make a program that detect a potential duplicates with 3 severity level.
let consider my data is only in two column, but with thousands row.
data in second column delimited only with comma. data example :
Number | Material
1 | helmet,valros,42
2 | helmet,iron,knight
3 | valros,helmet,42
4 | knight,helmet
5 | valros,helmet,42
6 | plain,helmet
7 | helmet, leather
and my 3 levels is :
very high : A,B,C vs A,B,C
high : A,B,C vs B,C,A
so so : A,B,C vs A,B
so far i just can make the first level, i don't know how to do the 2nd and the 3rd level.
what I've tried.
Sub duplicates_separation()
Dim duplicate(), i As Long
Dim delrange As Range, cell As Long
Dim shtIn As Worksheet, shtOut As Worksheet
Set shtIn = ThisWorkbook.Sheets("input")
Set shtOut = ThisWorkbook.Sheets("output")
x = 2
y = 1
Set delrange = shtIn.Range("b1:b10000") 'set your range here
ReDim duplicate(0)
'search duplicates in 2nd column
For cell = 1 To delrange.Cells.Count
If Application.CountIf(delrange, delrange(cell)) > 1 Then
ReDim Preserve duplicate(i)
duplicate(i) = delrange(cell).Address
i = i + 1
End If
Next
'print duplicates
For i = UBound(duplicate) To LBound(duplicate) Step -1
shtOut.Cells(x, 1).EntireRow.Value = shtIn.Range(duplicate(i)).EntireRow.Value
End Sub
duplicates detected by the program :
3 | valros,helmet,42
5 | valros,helmet,42
what i expected:
Number | Material
1 | helmet,valros,42
3 | valros,helmet,42
5 | valros,helmet,42
4 | knight,helmet
2 | helmet,iron,knight
i have an idea for detecting duplicates lv 2, but I think it will be so complicated and make the program slow.
turn column 2 to columns with "text to columns" command
sort column from A to Z (alphabetically)
concatenate the column
do countif like done in detecting duplicates lv 1
is there a way to detect the 2nd & 3rd level duplicates?
UPDATE
Yesterday I went to friend's house to consult about this problem, but his solution is in JAVA languange.. >which i don't understand
public class ali {
static void sPrint(String[] Printed) {
for (int iC = 0; iC < Printed.length; iC++) {
System.out.print(String.valueOf(Printed[iC]) + " | ");
}
System.out.println();
}
public static void main(String Args[]) {
int defaultLength = 10;
int indexID = 0;
int indexDesc = 1;
String[] DETECTORP1 = new String[defaultLength];
String[] DETECTORP2 = new String[defaultLength];
String[] DETECTORP3 = new String[defaultLength];
String[] DETECTORP4 = new String[defaultLength];
String[][] theString = new String[5][2];
theString[0] = new String[]{"1", "A, B, C, D"};
theString[1] = new String[]{"2", "A, B, C, D"};
theString[2] = new String[]{"3", "A, B, C, D, E"};
theString[3] = new String[]{"4", "A, B, D, C, E"};
theString[4] = new String[]{"5", "A, B, D, C, E, F"};
int P1 = 0;
int P2 = 0;
int P3 = 0;
int P4 = 0;
for (int iC = 0; iC < theString.length; iC++) {
System.out.println(theString[iC][indexID] + " -> " + theString[iC][indexDesc]);
}
for (int iC = 0; iC < theString.length; iC++) {
int LEX;
String theReference[] = theString[iC][indexDesc].replace(",", ";;").split(";;");
for (int iD = 0; iD < theString.length; iD++) {
if (iC != iD) {
String theCompare[] = theString[iD][1].replace(",", ";;").split(";;");
if (theReference.length == theCompare.length) {
LEX=0;
int theLength = theReference.length;
for (int iE = 0; iE < theLength; iE++) {
if (theReference[iE].equals(theCompare[iE])) {
LEX += 1;
}
}
if (LEX == theLength) {
DETECTORP1[P1] = theString[iC][indexID] + " WITH " + theString[iD][indexID];
P1 += 1;
} else {
LEX = 0;
for (int iF = 0; iF < theReference.length; iF++) {
for (int iG = 0; iG < theCompare.length; iG++) {
if (theReference[iF].equals(theCompare[iG])) {
LEX += 1;
break;
}
}
}
if (LEX == theReference.length) {
DETECTORP2[P2] = theString[iC][indexID] + " WITH " + theString[iD][indexID];
P2 += 1;
}
}
} else {
LEX = 0;
if (theReference.length > theCompare.length) {
for (int iF = 0; iF < theReference.length; iF++) {
for (int iG = 0; iG < theCompare.length; iG++) {
if (iG == iF) {
if (theReference[iF].equals(theCompare[iF])) {
LEX += 1;
break;
}
}
}
}
if (LEX <= theReference.length && LEX >= theCompare.length) {
DETECTORP3[P3] = theString[iC][indexID] + " WITH " + theString[iD][indexID];
P3 += 1;
}
} else {
LEX =0;
for (int iF = 0; iF < theCompare.length; iF++) {
for (int iG = 0; iG < theReference.length; iG++) {
if (iG == iF) {
if (theCompare[iF].equals(theReference[iF])) {
LEX += 1;
// System.out.println(theReference[iG] + "==" + theCompare[iG]);
break;
}
}
}
}
if (LEX <= theCompare.length && LEX >= theReference.length) {
DETECTORP3[P3] = theString[iC][indexID] + " WITH " + theString[iD][indexID];
P3 += 1;
}
}
}
}
}
}
sPrint(DETECTORP1);
sPrint(DETECTORP2);
sPrint(DETECTORP3);
}
}
how to do this in VBA?
Really, it depends how you want to define "severity level". Here's one way to do it, not necessarily the best: Use the Levensthein distance.
Represent each of your items by a one-character attribute symbol, e.g.
H helmet
K knight
I iron
$ Leather
^ Valros
╔ Plain
¢ Whatever
etc.
Then convert your Material lists into a string containing sequence of characters representing these attributes:
HIK = helmet,iron,knight
¢H = plain,helmet
Then compute the Levenshtein distance between those two strings. That will be your "severity level".
Debug.Print LevenshteinDistance("HIK","¢H")
'returns 3
Two implementations of the Levenshtein distance are shown in Wikipedia. And indeed you are in luck: someone on StackOverflow ported this to VBA.
In the comments section below, you say you don't like having to represent each of your possible attributes by one-character symbols. Fair enough; I agree this is a bit silly. Workaround: It is, in fact, possible to adapt the Levenshtein Distance algorithm to look not at each character in a string, but at each element of an array instead, and do comparisons based on that. I show how to make this change in my answer to your follow-up question.

Retrieving and manipulating data from file

The following code is supposed to retrieve the data related to the players info, sort it out and then rewrite the file now organized. Going to give an example of the files.
Original layout:
3
2 2
John 33 M 5
Anna 20 F 2
Rody 23 M 1
What it has to look like after the code:
3
2 2
Rody 23 M 1
Anna 20 F 2
John 33 M 5
I made the following code:
vector<string> playerScoresFromFile(const string filename) //Gets each one of those lines with the name, ..., and score of the person
{
int dim = filename[7] - '0'; // char to integer
vector<string> vec;
string line;
ifstream fin (filename.c_str());
for (int i = 0; i < dim + 1; i++)
{
getline(fin, line);
}
while(! fin.eof())
{
getline(fin, line);
vec.push_back(line);
}
return vec;
}
vector< vector<int> > readBoardFromFile(const string filename) //gets the board from the file (first 3 numbers)
{
int dim = filename[7] - '0'; // char to integer
string line;
vector< vector<int> >vec(dim, vector<int>(dim));
ifstream fin (filename.c_str());
int i = 0;
int j, k;
while(i < dim)
{
getline(fin, line);
int sizeOfLine = line.length();
if (line[0] == '\0')
{
break;
}
else
{
for (j = 0, k = 0; j < (sizeOfLine / 3); j++, k += 3)
{
string elementOfVectorStr = (line.substr(k,3));
int elementOfVectorInt = stringToInt(elementOfVectorStr);
if (abs(elementOfVectorInt) > 100) // when the element is a " ", the corresponding integer is always
{ // a very large number, positive or negative
elementOfVectorInt = 0;
}
vec[i][j] = elementOfVectorInt;
}
}
i++;
}
return vec;
}
vector<string> sortPlayersByTime (vector<string> &vec) // Creates a substring of the string extracted by "playerScoresFromFile" and analyses the times (Which are the last numbers to the right)
{
vector<int> timesInt(vec.size());
for (size_t i = 0; i < vec.size(); i++)
{
string str = vec[i];
timesInt[i] = stringToInt(str.substr(26));
}
for (size_t i = 0; i < vec.size() - 1; i++)
{
if(timesInt[i] > timesInt[i+1])
{
swap(vec[i], vec[i+1]);
}
}
return vec;
}
bool isOrdered (const vector<string> vec) //Checks if the vector is ordered
{
vector<int> timesInt(vec.size());
for (size_t i = 0; i < vec.size(); i++)
{
string str = vec[i];
timesInt[i] = stringToInt(str.substr(26));
}
for (size_t i = 0; i < vec.size() - 1; i++)
{
if(timesInt[i] > timesInt[i+1])
{
return false;
}
}
return true;
}
void writeBoardToFile(vector< vector<int> >&vec, string filename) //Rewrites the board to the file (Those first 3 numbers of the file)
{
ofstream fout(filename.c_str());
for (size_t i = 0; i < vec.size(); i++)
{
for (size_t j = 0; j < vec.size(); j++)
{
if(vec[i][j] != 0)
{
fout << setw(3) << vec[i][j];
}
else
{
fout << setw(3) << " ";
}
}
fout << endl;
}
fout << endl;
}
void vec_to_file(vector<string> vec, string filename) //Rewrites the vector to the file
{
ofstream fout(filename, ios::app);
for (int i = 0; i < vec.size(); i++)
{
fout << vec[i] <<endl;
}
}
void displayFile (string filename) //Displays the final board to check if it worked
{
vector<string> vec;
string line;
ifstream myfile (filename);
while ( ! myfile.eof() )
{
getline (myfile, line);
vec.push_back(line);
}
for (size_t i = 0; i < vec.size(); i++)
{
cout << vec[i] <<endl;
}
}
int main()
{
vector< vector<int> > vec = readBoardFromFile("puzzle_2x2_001.txt");
vector<string> vecxz = playerScoresFromFile("puzzle_2x2_001.txt");
writeBoardToFile(vec, "puzzle_2x2_001.txt"); //Writes the board to the file
while (! isOrdered(vecxz)) //This loop should run while they haven't been sorted out, but the program crashes here and I have no idea why.
{
sortPlayersByTime(vecxz);
}
//vec_to_file(vecxy, "puzzle_2x2_001.txt"); //Should write the vector to the file upon sorting them out successfully.
cin.get();
}
My problem is the program crashes everytime it gets to the while(! isOrdered(vecxz)) loop but I have no idea why. Can anyone give me a hand? I'd be thankful :)

c++ print out arrays incrementally

I am trying to print out arrays incrementally like this;
TractMultBox->Text = rows[0] + newline;
TractMultBox->Text += rows[1] + rows[0] + newline;
TractMultBox->Text += rows[2] + rows[1] + rows[0] + newline;
which would give an output like this
3
43
543
I can do fine with this code, however. It would like to use a for loop, that would make it easier, since I would like it to output all arrays until max is reached automatically.
I'm assuming you want to concatenate and not sum.
string text;
for (int i = 0; i < rows.count; ++i)
{
text = rows[i] + text;
TractMultBox->Text = text + newline;
}
for less lines of code.
string text = newline;
for (int i = 0; i < rows.count; ++i)
{
TractMultBox->Text = (text = rows[i] + text);
}
but that's a little hard to read.
Sounds like a job for a for loop indeed perhaps something like this:
#include <iostream>
int main()
{
int rows[3] = {3, 4, 5};
for (int i(0); i < 3; ++i)
{
for (int j(i); j >= 0; --j)
std::cout << rows[j];
std::cout << "\n";
}
std::cin.get();
return 0;
}
If rows contained 345 this would give you the following output:
3
43
543
Not sure if that's what you wanted but you can adjust the loops accordingly. The key is to have 2 for loops.
Edit: Changed to self contained example you can play with
What about a double loop like:
for (int i = 0; i < maxNRows; ++i)
{
for (int j = 0; j < i; ++j)
{
TractMultBox->Text += rows[j];
}
TractMultBox->Text += newline;
}