Δημοσιεύτηκε: 21 Ιούλ 2011, 18:44
konnn έγραψε:Ποιό ολοκληρωμένο πρόγραμμα που δέχεται ακόμα βελτιώσεις όπως αφαίρεση διπλών ζευγαριών.Spoiler: show
Φίλε konn πως βγάζεις άκρη με αυτό τον συμπιεσμένο κώδικα και με αυτές τις ονομασίες μεταβλητών;;;;;;;;;;;;;;
Δεν έλεγξα τον αλγόριθμο, παρατήρησα όμως πως δεν δουλεύει με αρνητικούς αριθμούς. Επειδή όμως μου βγήκαν λιγάκι τα μάτια για να κάνω ευανάγνωστο τον κώδικα δεν είχα κουράγιο μετά να κοιτάξω και τον αλγόριθμο.
Ωστόσο, άλλαξα ονομασίες μεταβλητών, έκανα φορσέ τους αριθμούς σε θετικούς (με το macro ABS(x)) αφαίρεσα το διπλό τύπωμα των ζευγαριών (με χρήση πίνακα χαρτογράφησης) κι αφαίρεσα το τύπωμα ζευγαριών όταν οι 2 αριθμοί είναι ίσοι.
- Κώδικας: Επιλογή όλων
/* Αυτό προγραμματάκι βρίσκει εάν ένας αριθμός έχει φίλο */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ABS(x) (x) > 0 ? (x) : -(x)
// -----------------------------------------------------------------------------
// Επιστρέφει το άθροισμα όλων των διαιρετών του num
//
int div_sum( int num )
{
int i=0, sum=0;
for (i=1; i <= num/2; i++)
if ( num % i == 0 ) // το i είναι διαιρέτης του num
sum += i; // πρόσθεσέ το στο sum
return sum;
}
// -----------------------------------------------------------------------------
int main( void )
{
FILE * pFile;
int low=0, high=0, num1=0, num2=0;
puts("ΣΗΜΕΙΩΣΗ:\nτυχόν αρνητικοί αριθμοί μετατρέπονται σε θετικούς!\n");
printf ("Κάτω όριο αναζήτησης (πλην του αριθμού 0): ");
scanf ("%d", &low);
low = ABS(low);
printf ("Άνω όριο αναζήτησης: ");
scanf ("%d", &high);
high = ABS(high);
if ( high < low ) // άνω όριο μικρότερο του κάτω ορίου?
{ // ενάλλαξέ τα
int temp = low;
low = high;
high = temp;
}
/* Χρησιμοποιούμε έναν δυναμικό πίνακα χαρτογράφησης όλων των
* αριθμών μεταξύ low και high, που τον αρχικοποιούμε με την
* τιμή 0 σε όλα του κελιά. Όταν βρούμε έναν αριθμό num1 που έχει
* φιλικό αριθμό num2, χαρτογραφούμε τον num1 στον πίνακα με τιμή 1
* και τυπώνουμε το ζευγάρι στην οθόνη μόνο αν ο num2 δεν είναι
* ήδη χαρτογραφημένος.
*/
int lenmap = high - low; // μήκος του πίνακα χαρτογράφησης
char mapnums[ lenmap ]; // πίνακας χαρτογράφησης αριθμών
memset( mapnums, 0, lenmap * sizeof(char) ); // αρχικοποίηση πίνακα με 0
pFile = fopen ("myfile.txt","w");
if ( !pFile )
puts("\n\t*** σημείωση: το άνοιγμα του αρχείου απέτυχε\n");
putchar('\n');
for ( num1=low; num1 < high; num1++ )
{
num2 = div_sum( num1 );
if ( div_sum( num2 ) != num1 ) // ο num1 δεν έχει φιλικό αριθμό
continue;
// σε αυτό το σημείο οι num1 και num2 είναι φίλοι
// διότι: div_sum( num2 ) == num1
mapnums[num1-low] = 1; // χαρτογράφηση του num1
// τύπωμα του ζευγαριού αριθμών μόνο όταν δεν είναι ίσοι
// μεταξύ τους και μόνο όταν ο num2 είναι αχαρτογράφητος
if ( num1 != num2 && mapnums[num2-low] == 0 )
{
printf("Οι αριθμοί %d και %d είναι φίλοι.\n", num1, num2 );
if ( pFile )
fprintf(pFile, "Οι αριθμοί %d και %d είναι φίλοι.\n", num1, num2);
}
}
if ( pFile)
fclose (pFile);
fflush(stdin); getchar();
exit(EXIT_SUCCESS);
}