int function2 (const char * string1) स्ट्रिंग में दिखने वाले अद्वितीय अंकों की संख्या लौटाता है, उदा. function2 ("ab512af6kc1") -> 3.

int function2(const char* string1) {
  int zero = 0, one = 0, two = 0, three = 0, four = 0, five = 0, six = 0,
      seven = 0, eight = 0, nine = 0, counter = 0;

  for (int i = 0; i < strlen(string1); i++) {
    if (string1[i] == '0') {
      zero++;
    }
    if (string1[i] == '1') {
      one++;
    }
    if (string1[i] == '2') {
      two++;
    }
    if (string1[i] == '3') {
      three++;
    }
    if (string1[i] == '4') {
      four++;
    }
    if (string1[i] == '5') {
      five++;
    }
    if (string1[i] == '6') {
      six++;
    }
    if (string1[i] == '7') {
      seven++;
    }
    if (string1[i] == '8') {
      eight++;
    }
    if (string1[i] == '9') {
      nine++;
    }
  }
  if (zero == 1) {
    counter++;
  }
  if (one == 1) {
    counter++;
  }
  if (two == 1) {
    counter++;
  }
  if (three == 1) {
    counter++;
  }
  if (four == 1) {
    counter++;
  }
  if (five == 1) {
    counter++;
  }
  if (six == 1) {
    counter++;
  }
  if (seven == 1) {
    counter++;
  }
  if (eight == 1) {
    counter++;
  }
  if (nine == 1) {
    counter++;
  }

  return counter;
}

इस कोड में यह सब सही है, लेकिन यह थोड़ा लंबा है। क्या कोई मेरी मदद कर सकता है और छोटा कोड लिख सकता है? यह एकमात्र तरीका है जिससे मैं इस अभ्यास को माप सकता हूं।

c++
0
xyz9 24 मार्च 2020, 00:23
2
क्या आपने अभी तक सरणियों और लूपों का उपयोग करना सीखा है? स्विच-केस के बारे में क्या? क्या "12334" को 3 या 4 लौटाना चाहिए? (आपका कोड 3 वापस आ जाएगा।)
 – 
Dave S
24 मार्च 2020, 00:26
1
for(int i = 0; i < strlen(string1); i++) { -- strlen को for लूप कंस्ट्रक्शन के हिस्से के रूप में इस तरह कॉल न करें। प्रत्येक पुनरावृत्ति के लिए, आप strlen को कॉल कर रहे हैं। कल्पना करें कि स्ट्रिंग 100 वर्ण है - यानी 10000 पुनरावृत्तियां की जा रही हैं।
 – 
PaulMcKenzie
24 मार्च 2020, 00:28
मानक पुस्तकालय और std::unique का उपयोग करने पर विचार करें
 – 
Tas
24 मार्च 2020, 00:31
1
ध्यान न देना। प्रोग्रामर को आमतौर पर लिखे गए कोड की मात्रा के लिए भुगतान किया जाता है। :)
 – 
Vlad from Moscow
24 मार्च 2020, 00:41
1
नहीं, यह नहीं होना चाहिए अगर मेरे पास दो समान संख्याएं हैं तो यह मुझे 0 देता है, अगर मेरे पास "ab512af6kc" था -> वापसी 4।
 – 
xyz9
24 मार्च 2020, 00:53

5 जवाब

आप 10 चर के बजाय एक सरणी का उपयोग कर सकते हैं। वर्ण को पूर्णांक में परिवर्तित करके सरणी में अनुक्रमणिका की गणना करें।

int function2(const char *in) {
   // Array to hold digits occurence counts.
   unsigned digits[10]{};
   // Iterate over the characters in input.
   // Better (auto i : std::string_view(in)) in C++17.
   for (auto i = in; *i; ++i) {
        if (isdigit(*i)) {
            // Increment the proper digit index.
            digits[*i - '0']++;
        }
   }
   int count = 0;
   // Go through digit occurences.
   for (auto i : digits) {
      // If the digit occurred only once.
      if (i == 1) {
         // Increment the count.
         count++;
      }
   }
   return count;
}
1
KamilCuk 24 मार्च 2020, 00:51

अपने कोड को छोटा करने के लिए, 10 अलग-अलग चर के बजाय एक सरणी का उपयोग करें:

int digits[10] = {0}; // instead of int zero = 0, one = 0, ...

यह जांचने के लिए कि क्या char किसी अंक का प्रतिनिधित्व है, isdigit का उपयोग करें:

if (isdigit(string1[i])) // instead of if (string1[i] == '0'), if (string1[i] == '1'), ...

एकमात्र गैर-तुच्छ हिस्सा char को संबंधित int में बदलना है:

string1[i] - '0'

यह कोड एक अंक के वर्ण कोड से 0 (आमतौर पर 48) का वर्ण कोड घटाता है (आमतौर पर 1 के लिए 49, 2 के लिए 50, ..., 57 के लिए 9). परिणाम आपके काउंटरों की सरणी के लिए एक अनुक्रमणिका है।

तो, उचित सरणी तत्व को बढ़ाने के लिए, निम्न कोड का उपयोग करें:

digit = string1[i] - '0';
digits[digit]++; // instead of zero++, one++, ...

कोड इनपुट स्ट्रिंग पर जाने के बाद, एक बार दिखाई देने वाले अंकों की संख्या गिनें:

int counter = 0;
for (digit = 0; digit < 10; ++digit)
{
    if (digits[digit] == 1)
        ++counter;
}
1
eesiraed 24 मार्च 2020, 08:32

अद्वितीय अंकों का ट्रैक रखने के लिए हैश तालिका संग्रह वर्ग का उपयोग करें। इस मामले में, unordered_set ठीक काम करेगा। चार को पूर्णांक में बदलने से भी परेशान न हों। आप केवल '0' और '9' के बीच अद्वितीय वर्णों की तलाश कर रहे हैं।

#include <string>
#include <unordered_set>

size_t getUniqueDigits(const std::string& string1)
{
    std::unordered_set<char> table;
    for (char c : string1)
    {
        if ((c >= '0') && (c <= '9'))
        {
            table.insert(c);
        }
    }
    return table.size();
}

एक अधिक पारंपरिक "सी" आधारित समाधान जो किसी भी std :: संग्रह या वस्तुओं का उपयोग नहीं करता है वह "सेट" होने के लिए एक सरणी का उपयोग करना है

int getUniqueDigits(const char* string1)
{
    int table[10] = {0};
    int count = 0;
    const size_t len = (string1 != nullptr) ? strlen(string1) : 0;

    for(size_t i = 0; i < len; i++)
    {
        char c = string1[i];
        if ((c >= '0') && (c <= '9'))
        {
            table[c - '0'] = 1;
        }
    }

    for (char j = '0'; j <= '9'; j++)
    {
        count += table[j];
    }

    return count;
}
1
selbie 24 मार्च 2020, 22:09
उस "पारंपरिक 'सी' आधारित समाधान" में बहुत कम ओवरहेड है। मैं इसे दूसरे की तुलना में बेहतर समाधान के रूप में देखता हूं।
 – 
Pete Becker
24 मार्च 2020, 01:15
10 अंकों के लिए एक हैश तालिका पूरी तरह से ओवरकिल है।
 – 
eesiraed
24 मार्च 2020, 08:32
- यह इस बात पर निर्भर करता है कि आप किसके लिए ऑप्टिमाइज़ करना चाहते हैं। रखरखाव बनाम गति। कहा जा रहा है कि, दोनों समाधानों को समझना काफी आसान है - इसलिए दोनों संतुष्ट हैं। यदि आपका प्रोजेक्ट काफी बड़ा है, तो संभावना अधिक है कि आप पहले ही स्ट्रिंग और सेट में लिंक करने के लिए कीमत चुका चुके हैं। आप उनका इस्तेमाल भी कर सकते हैं।
 – 
selbie
24 मार्च 2020, 09:08

उदाहरण के लिए इस प्रदर्शन कार्यक्रम में एक साधारण सरणी का उपयोग करें

#include <iostream>

size_t unique_digits( const char *s )
{
    unsigned char digits[10] = { 0 };

    for ( ; *s; ++s )
    {
        if ( '0' <= *s && *s <= '9' )
        {
            if ( digits[*s - '0'] != 2 ) ++digits[*s - '0'];
        }
    }

    size_t count = 0;

    for ( unsigned char c : digits ) count += c == 1;

    return count;
}

int main() 
{
    std::cout << unique_digits( "ab512af6kc1" ) << '\n';

    return 0;
}

प्रोग्राम आउटपुट है

3

या आप तत्व प्रकार size_t की सरणी घोषित कर सकते हैं। इस मामले में फ़ंक्शन निम्न तरीके से दिखेगा

#include <iostream>

size_t unique_digits( const char *s )
{
    size_t digits[10] = { 0 };

    for ( ; *s; ++s )
    {
        if ( '0' <= *s && *s <= '9' )
        {
            ++digits[*s - '0'];
        }
    }

    size_t count = 0;

    for ( unsigned char c : digits ) count += c == 1;

    return count;
}

int main() 
{
    std::cout << unique_digits( "ab512af6kc1" ) << '\n';

    return 0;
}
0
Vlad from Moscow 24 मार्च 2020, 01:20
चेक if ( digits[*s - '0'] != 2 ) का क्या लाभ है?
 – 
cigien
24 मार्च 2020, 00:59
एक स्ट्रिंग बहुत बड़ी हो सकती है। यदि आप इसे हमेशा बढ़ाना चाहते हैं तो इस मामले में आपको तत्व प्रकार size_t के साथ एक सरणी घोषित करनी होगी।
 – 
Vlad from Moscow
24 मार्च 2020, 01:00
यह समझ आता है। तो क्या size_t सरणी रखना बेहतर नहीं होगा, और चेक से बचें?
 – 
cigien
24 मार्च 2020, 01:02
यह चेक बहुत तेज है।
 – 
Vlad from Moscow
24 मार्च 2020, 01:03
ज़रूर, लेकिन यह चेक करने से तेज़ नहीं हो सकता है, है ना? या यह किसी भी तरह से चेक करना बेहतर है, और एक अहस्ताक्षरित चार सरणी है?
 – 
cigien
24 मार्च 2020, 01:04

मुझे लगता है कि आपके पास पहले से ही कई अच्छे समाधान हैं।

यहाँ वैसे भी मेरा संस्करण है

int function2(const char* string1) {
    int count[10] = {0};
    int counter = 0;
    int i;
    for(i = 0; i < strlen(string1); i++)
        int a = (++count[string1[i]-'0']);
        if(a == 1)counter++;
        if(a == 2)counter--;
    return counter;
}

मैंने कोशिश नहीं की है। आशा है कि कोई त्रुटि नहीं है

संपादित करें: मैंने कोशिश की। ऐसा लगता है कि अब ठीक काम कर रहा है।

0
Tony Barletta 24 मार्च 2020, 01:48
क्या आप समझा सकते हैं कि समस्या क्या है?
 – 
Tony Barletta
24 मार्च 2020, 01:37
<10 समस्या इस स्थिति में है काउंटर <10. और इस कथन में यदि((++count[string1[i]-'0']) == 1)काउंटर++;
 – 
Vlad from Moscow
24 मार्च 2020, 01:38
यह एक अतिरिक्त जांच है। यदि हमें 10 वर्ण मिलते हैं तो स्ट्रिंग को पार्स करना जारी रखने की कोई आवश्यकता नहीं है। C भाषा && ऑपरेटर को सही प्राथमिकता देती है। स्थिति ठीक होनी चाहिए। क्या आप बेहतर समझा सकते हैं कि त्रुटि क्या है? क्या आपने मेरा कोड चलाया है?
 – 
Tony Barletta
24 मार्च 2020, 01:40
प्रश्न के अनुसार अद्वितीय अंकों का अर्थ उन अंकों से है जो स्ट्रिंग में दोहराए नहीं जाते हैं।
 – 
Vlad from Moscow
24 मार्च 2020, 01:44
क्या आप मुझे बता सकते हैं कि यहाँ क्या हो रहा है? "इंट ए = (++ गिनती [स्ट्रिंग 1 [i] - '0']);"
 – 
xyz9
24 मार्च 2020, 02:26