I need to find top 3 of 10 integer numbers without using arrays. I must find index of them and print array number with indexing.
For example if array is {0,1,2,3,4,5,6,7,8,9};
I must find that first=9, second=8,third=7 and print array as:
array[first]
array[second]
array[third].
#include <stdio.h>
int main() {
double arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
double s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8,
s9 = 9;
int first = 0, second=0,third=0;
for (i = 0; i < 10; i ) {
if (s1 >= s0 && s1 >= s2 && s1 >= s3 && s1 >= s4 && s1 >= s5 && s1 >= s6 &&
s1 >= s7 && s1 >= s8 && s1 >= s9)
first = 1;
if (s2 >= s0 && s2 >= s1 && s2 >= s3 && s2 >= s4 && s2 >= s5 && s2 >= s6 &&
s2 >= s7 && s2 >= s8 && s2 >= s9)
first = 2;
if (s3 >= s0 && s3 >= s1 && s3 >= s2 && s3 >= s4 && s3 >= s5 && s3 >= s6 &&
s3 >= s7 && s3 >= s8 && s3 >= s9)
first = 3;
if (s4 >= s0 && s4 >= s1 && s4 >= s2 && s4 >= s3 && s4 >= s5 && s4 >= s6 &&
s4 >= s7 && s4 >= s8 && s4 >= s9)
first = 4;
if (s5 >= s0 && s5 >= s1 && s5 >= s2 && s5 >= s3 && s5 >= s4 && s5 >= s6 &&
s5 >= s7 && s5 >= s8 && s5 >= s9)
first = 5;
if (s6 >= s0 && s6 >= s1 && s6 >= s2 && s6 >= s3 && s6 >= s4 && s6 >= s5 &&
s6 >= s7 && s6 >= s8 && s6 >= s9)
first = 6;
if (s7 >= s0 && s7 >= s1 && s7 >= s2 && s7 >= s3 && s7 >= s4 && s7 >= s5 &&
s7 >= s6 && s7 >= s8 && s7 >= s9)
first = 7;
if (s8 >= s0 && s8 >= s1 && s8 >= s2 && s8 >= s3 && s8 >= s4 && s8 >= s5 &&
s8 >= s6 && s8 >= s7 && s8 >= s9)
first = 8;
if (s9 >= s0 && s9 >= s1 && s9 >= s2 && s9 >= s3 && s9 >= s4 && s9 >= s5 &&
s9 >= s6 && s9 >= s7 && s9 >= s8)
first = 9;
}
printf("First: %g", arr[first]);
return 0;
}
This finds first element of array. How could I find second and third element? Restriction of not using arrays makes this tough.
CodePudding user response:
Here is my solution:
#include <stdio.h>
#include <float.h>
int main( void )
{
double arr[] =
{ 17.1, 12.3, 7.2, 35.7, 14.2, 12.4, 6.9, 19.1, 34.9, 5.5 };
//This declaration has been modified to use the array only to
//ensure consistency with the array. I do not consider this to
//be cheating. This declaration can be replaced with the
//original code and the program will still work.
double
s0 = arr[0], s1 = arr[1], s2 = arr[2], s3 = arr[3],
s4 = arr[4], s5 = arr[5], s6 = arr[6], s7 = arr[7],
s8 = arr[8], s9 = arr[9];
int first = 0, second = 0, third = 0;
for ( int i = 0; i < 3; i )
{
int largest_index;
double *p_largest;
for ( int j = 0; j < 10; j )
{
double *p;
//the following loop effectively does "p = &arr[j]", without
//actually using the array, but instead making the pointer
//point to the corresponding lone variable instead
switch ( j )
{
case 0:
p = &s0;
break;
case 1:
p = &s1;
break;
case 2:
p = &s2;
break;
case 3:
p = &s3;
break;
case 4:
p = &s4;
break;
case 5:
p = &s5;
break;
case 6:
p = &s6;
break;
case 7:
p = &s7;
break;
case 8:
p = &s8;
break;
case 9:
p = &s9;
break;
}
//determine whether *p is the largest value in the
//array
if (
*p >= s0 && *p >= s1 && *p >= s2 && *p >= s3 &&
*p >= s4 && *p >= s5 && *p >= s6 && *p >= s7 &&
*p >= s8 && *p >= s9
)
{
largest_index = j;
}
}
//This "switch" statement effectively does
//"p_largest = &arr[largest_index];", but does not
//point inside the array. Instead, it points to the
//corresponding lone variable.
switch ( largest_index )
{
case 0:
p_largest = &s0;
break;
case 1:
p_largest = &s1;
break;
case 2:
p_largest = &s2;
break;
case 3:
p_largest = &s3;
break;
case 4:
p_largest = &s4;
break;
case 5:
p_largest = &s5;
break;
case 6:
p_largest = &s6;
break;
case 7:
p_largest = &s7;
break;
case 8:
p_largest = &s8;
break;
case 9:
p_largest = &s9;
break;
}
//set "first", "second" or "third", depending on which
//loop iteration we currently are in
switch ( i )
{
case 0:
first = largest_index;
break;
case 1:
second = largest_index;
break;
case 2:
third = largest_index;
break;
}
//set highest number to lowest possible number, so that
//it won't be the highest again in the next iteration of
//the loop
*p_largest = -DBL_MAX;
}
printf( "First: %g\n", arr[first] );
printf( "Second: %g\n", arr[second] );
printf( "Third: %g\n", arr[third] );
}
This program has the following (correct) output:
First: 35.7
Second: 34.9
Third: 19.1
This solution works by setting the highest found value to the lowest possible value (which is -DBL_MAX
), so that the next iteration of the loop will not find the same value again as the highest value, but will instead find the next highest value.
For comparison, here is my much cleaner solution which uses arrays instead:
#include <stdio.h>
#include <float.h>
int main( void )
{
double arr[] =
{ 17.1, 12.3, 7.2, 35.7, 14.2, 12.4, 6.9, 19.1, 34.9, 5.5 };
double largest_values[3];
for ( int i = 0; i < 3; i )
{
double largest_value = -DBL_MAX;
int largest_index;
for ( int j = 0; j < 10; j )
{
if ( arr[j] >= largest_value )
{
largest_value = arr[j];
largest_index = j;
}
}
largest_values[i] = largest_value;
arr[largest_index] = -DBL_MAX;
}
printf( "First: %g\n", largest_values[0] );
printf( "Second: %g\n", largest_values[1] );
printf( "Third: %g\n", largest_values[2] );
}
CodePudding user response:
This is a bit of a boneheaded approach but given your restrictions, how about something like this?
public static void Main()
{
double s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8, s9 = 9;
var arr = new double[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int first = 0, second=0, third=0;
first = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, -1, -1);
second = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, first, -1);
third = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, first, second);
Console.WriteLine(arr[first]);
Console.WriteLine(arr[second]);
Console.WriteLine(arr[third]);
}
private static int FindMax(
double s0,
double s1,
double s2,
double s3,
double s4,
double s5,
double s6,
double s7,
double s8,
double s9,
int indexOneToIgnore,
int indexTwoToIgnore){
double max = 0;
int indexOfMax = 0;
if(Math.Max(max, s0) > max && indexOneToIgnore != 0 && indexTwoToIgnore != 0)
{
max = s0;
indexOfMax = 0;
}
if(Math.Max(max, s1) > max && indexOneToIgnore != 1 && indexTwoToIgnore != 1)
{
max = s1;
indexOfMax = 1;
}
if(Math.Max(max, s2) > max && indexOneToIgnore != 2 && indexTwoToIgnore != 2)
{
max = s2;
indexOfMax = 2;
}
...
return indexOfMax;
}
Full example here: .Net Fiddle.
Could be shortened quite a bit by moving the if statements to a separate function but since you´d need to adopt it to C anyway I´d leave that to you.
CodePudding user response:
Here is a simple way of doing it that iterates over each element, and moves it up the rankings of third, second and first until the index holding that rank points to a larger or equal value. You will notice that I am initializing the indexes with -1, I do this because if they all started with 0 and 0 was in the top 2 (it would be fine if it was the third), then no other numbers would replace it and your top three would all be the initial value, even if there was only one of that value. (I will add another work around below)
#include <stdio.h>
int main() {
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int first = -1, second = -1, third = -1;
int temp;
for (int i = 0; i < 10; i ) {
if (third == -1 || arr[i] > arr[third]) { //greater than third
third = i;
if (second == -1 || arr[i] > arr[second]) { //than second
temp = second;
second = third;
third = temp;
if (first == -1 || arr[i] > arr[first]) { //than first
temp = first;
first = second;
second = temp;
}
}
}
}
printf("First: %d\n", arr[first]);
printf("Second: %d\n", arr[second]);
printf("Third: %d\n", arr[third]);
return 0;
}
You will notice that each of the if statements first have to check if the rank hasn't been filled (== -1), which is not ideal. To avoid this we can initialize the three ranks to point to the smallest value, which takes computational power to find, but if you count the integer comparisons, its less.
//find index of the min
int min = 0;
for (int i = 0; i < 10; i ) {
if (arr[i] < arr[min]) {
min = i;
}
}
//set each rank to the index of the min
int first = min, second = min, third = min;
This would be inserted into the fist code block in place of the original initialization of the three ranks. You would then be able to remove the three occurrences of rank == -1 ||
in the if statements.
CodePudding user response:
Here is a decent algorithm
int* top_3(const int* arr_of_10) {
static int top_3[3];
int next_highest = 0;
for (int appended = 0; appended < 3; appended ) {
int highest_of = 0;
for (int index = 0; index < 10; index ) {
if ((highest < arr_of_10[index]) && ((highest < next_highest) || !next_highest)) {
highest = arr_of_10[index];
}
}
top_3[appended] = highest;
next_highest = highest;
}
return top_3;
}