Wyszukiwanie tablicy – wartość graniczna

0

Cześć, mam problem z takim programem:
wyszukiwanie elementu o zadanej wartości – tablica z wartościami zmiennoprzecinkowymi – zadanie granicznej wartości różnicy między
liczbami, poniżej której dwie liczby są traktowane jako identyczne.

Ja to próbuję zrobić w taki sposób,jednak program nie działa poprawnie.

#include <stdio.h>
 int main(void)
 {
 	int a;
	 float tab[5]={2.5,2.6,3.4,3.7,5};
 	printf("POdaj element: ");
 	scanf("%d", &a);
 	for(int i=0;i<5;i++)
 	{
 		if(tab[i+1]-tab[i]<=0.4 && tab[i+1]-tab[i]>0.1)
		{
			tab[i+1]=tab[i];
			
		 } 
		 if(tab[i]==a)
		 {
		 	printf("Element znaleziony na pozycji %d",i);
		 	break;
		 }
		 else
		 {
		 	printf("Nie ma takiego elementu");
break;
		 }
}
}
0
if(tab[i+1]-tab[i]<=0.4 && tab[i+1]-tab[i]>0.1)

o co tu chodzi? Po co porównujesz różne elementy tablicy i to jeszcze w taki dziwny sposób?

Masz sprawdzić czy wartość bezwzględna z (a-b) jest mniejsza niż epsilon, nic więcej.

1

Dlaczego tworzysz tablicę zawierającą pięć elementów, lecz iterujesz już do dziesięciu? (a tak właściwie to jedenastu, ponieważ masz tab[i+1])

0

Czy to tak może wyglądać?

if(tab[i+1]-tab[i]<=abs(0.4) && tab[i+1]-tab[i]>abs(0.1))

0

Kamilka, zapoznaj się z tym

1

Bardziej w stylu:

if (abs(tab[i+1] - tab[i]) ...) {
}

Koniec końców abs(0.4) jest stałą i wynosi właśnie 0.4, podczas gdy abs(tab[i+1] - tab[i]) stałą już nie jest.

0
Patryk27 napisał(a):

Bardziej w stylu:

if (abs(tab[i+1] - tab[i]) ...) {
}

Koniec końców abs(0.4) jest stałą i wynosi właśnie 0.4, podczas gdy abs(tab[i+1] - tab[i]) stałą już nie jest.

Za twoją radę tak napisałam, jednak dalej cos jest źle

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	float a;
	float tab[5] = { 2.5,2.6,3.4,3.7,5 };
	printf("POdaj element: ");
	scanf("%f", &a);
	for (int i = 0; i < 5; i++)
	{

		if (abs(tab[i] - a) <=0.3 || tab[i] == a)
		{

			printf(" Element jest na pozycji %d ", i);
			break;
		}
		else
		{
			printf("Nie ma elementu! ");
			break;
		}

	}
		
		
	}
2
  1. if (abs(tab[i] - a) <=0.3 || tab[i] == a) - jeśli tab[i] == a, to na pewno abs(tab[i] - a) <= 0.3, prawda? Więc ten drugi warunek jest zbędny.
  2. Twoja pętla wykonuje się zawsze tylko raz, ponieważ po pierwszej iteracji w każdej sytuacji odpalasz break;.
0
#include <cstdio> 
#include <cmath>


float table[5] = { 2.5, 2.6, 3.4, 3.7, 5 };
float epsilon = 0.01f;

bool ApproximatelyEqual (float a, float b)
{
  return fabs (a - b) <= ((fabs (a) < fabs (b) ? fabs (b) : fabs (a)) * epsilon);
}
 
float GetInput()
{  float a;
  printf ("Podaj szukany element: ");
  scanf ("%f", &a);
  return a;
}

int DoSearch(float number)
{   
    for (int i= 0; i < 5; i++)
    {
         
      if (ApproximatelyEqual(number, table[i]))
        {     
         return  i;
        }
    }
   return -1;
}

void ShowResult(int position )
{
 if ( position == -1)
    {
      printf ("Nie ma elementu! ");
    }
    else 
    {
     printf ("Element jest na pozycji %d ", position);
    }
}
 
int main (void)
{ 
 float number = GetInput();
 int position = DoSearch(number);
 ShowResult(position);
}

0
Patryk27 napisał(a):
  1. if (abs(tab[i] - a) <=0.3 || tab[i] == a) - jeśli tab[i] == a, to na pewno abs(tab[i] - a) <= 0.3, prawda? Więc ten drugi warunek jest zbędny.
  2. Twoja pętla wykonuje się zawsze tylko raz, ponieważ po pierwszej iteracji w każdej sytuacji odpalasz break;.

Zmieniłam to tak jak pokazałeś, jednak program się kompiluje, ale nie działa poprawnie

#include <stdio.h>
#include <stdlib.h>
#define gran 0.3f
int main(void)
{
    float a;
    float tab[5] = { 2.5,2.6,3.4,3.7,5 };
    printf("POdaj element: ");
    scanf("%lf", &a);
    for (int i = 0; i < 5; i++)
    {
 
        if (abs(tab[i] - a) <=gran)
        {
 
            printf(" Element jest na pozycji %d ", i);
            return 0;
        }
        else
        {
            printf("Nie ma elementu! ");
            return 0;
        }
    
 
    }
 
    }
1

Nie, nie zrobiłaś tak jak napisałem - w dalszym ciągu Twoja pętla zawsze kończy się po jednym obrocie.

1

Kamila...

#include <stdio.h>
#include <stdlib.h>
#define gran 0.3f
int main(void)
{
    float a;
    float tab[5] = { 2.5,2.6,3.4,3.7,5 };
    printf("POdaj element: ");
    scanf("%lf", &a);
    for (int i = 0; i < 5; i++)
    {

        if (abs(tab[i] - a) <=gran)
        {

            printf(" Element jest na pozycji %d ", i);
            return 0;// <= ZARÓWNO TUTAJ...
        }
        else
        {
            printf("Nie ma elementu! ");
            return 0;// <=...JAK I TUTAJ MASZ PRZERYWANIE PĘTLI PRZY PIERWSZYM PRZEJŚCIU
        }

    }
}

teraz widzisz?

0

W obu wypadkach ścieżki wykonywania programu, tj zarówno dla spełnionego if-a, jak i nie spełnionego masz return 0, co w tym konkretnym miejscu powoduje zakończenie programu, i siłą rzeczy tylko jednokrotne wykonanie się pętli.
Pytanie co za efekt chcesz osiągnąć, jak chcesz zrobić pełne 5 iteracji pętli to return 0 musisz przenieść przed ostatnią klamrę zamykającą main()

0

WIęc return 0 powinien być tylko w przypadku jeśli pierwszy warunek będzie spełniony, czyli tylko w if()

0

Jeśli istotnie chcesz przerwać w tym momencie pętlę, to teoretycznie tak. Ale powiedz mi Kamila, jakiego efektu byś oczekiwała w przypadku danych wejściowych:

float tab[5]={2.5,2.6,2.5,3.7,2.5};

kiedy dasz poszukiwanie 2.5f?

0

To Kamilka, aby uzyskać pożądany efekt wyrzuć return 0 z obu ścieżek wykonywania się pętli. I to wszystko, program po takiej zmianie sprawdzi każdy element w tablicy.
EDIT:
Co najwyżej przerób printfa w else na:

printf(" Element na pozycji %d nie spełnia warunku", i);
0
#include <stdio.h>
#include <math.h>

int main(void) {
	const float gran = 0.3f;
	
	float arr[] = {1.5f, 2.5f, 3.5f, 4.5f, 4.2f};
	float input;
	scanf("%f", &input);
	for (int i = 0; i < sizeof(arr)/sizeof(float); ++i)
		if (fabs(arr[i] - input) <= gran)
			printf("found at %i\n", i);

	return 0;
}
1

No więc Kamilka tak - skoro maksymalna ilość cyfr po przecinku to 1 można posłużyć się sztuczką pomnożenia przez 10 aby pozbyć się nieprecyzyjnej arytmetyki zmiennoprzecinkowej. Po tej zmianie program wygląda tak:

#include <stdio.h>
#include <stdlib.h>

#define gran 0.3f

int main(void)
{
    float tab[5] = { 2.5, 2.6, 3.4, 3.7, 5};
 
    float a;   
    printf("POdaj element: ");
    scanf("%f", &a);
    
    a = a * 10;
    int granC = gran * 10;
    
    for (int i = 0; i < 5; i++)
    {
        int f = (int) abs(tab[i] * 10 - a);
 
        if (f <= granC)
        {
 
            printf("Element %f na pozycji %d pasuje \n", tab[i], i);
        }
        else
        {
            printf("Element %f na pozycji %d nie pasuje \n", tab[i], i);
        }
 
    }
}

https://onlinegdb.com/S1ZYbsNAX
testowałem dla 3.5, 3.6, 2.2, 4.0, i dobrze znalazło.

1

Nie wiem po co takie kombinacje, bez problemu to działa dla zmiennoprzecinkowych:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define gran 0.3f
#define N 5
int main(void)
{
    float a;
    float tab[N] = { 2.5,2.6,3.4,3.7,5};
    int count = 0;
    printf("Podaj element: ");
    scanf("%f", &a);
    for (int i = 0; i < N; i++)
    {
        if (fabs(tab[i] - a) <= gran)
        {
            printf(" Element jest na pozycji %d\n", i);
            count++;
        }
    }
    if (!count) {
        printf("Brak takiego elementu");
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1