PHP फ़ंक्शन 0 यदि लूप में नकल कर रहा है [डुप्लिकेट]

Aug 18 2020

मेरे पास एक सरल PHP फ़ंक्शन है जो एक पूर्णांक में एक विशिष्ट अंक की संख्या को गिनता है

function countOccurrence($number, $digit){
    $result = 0; while ($number > 0){
        $lastDigit = $number % 10;
        if($lastDigit === $digit){
            $result++; } $number = ($number - $lastDigit)/10;
    }
    return $result;
}

जो अपने आप पर पूरी तरह से ठीक काम करता है [परिक्षण के साथ परीक्षण किया गया (1111, 1) और 4 लौटे]

लेकिन जब मैं इसे लूप में एक नंबर रेंज के लिए उपयोग करता हूं तो यह हमेशा 0 रिटर्न देता है।

if (isset($_POST['submit'])){
    $startNum = $_POST['startNum'];
    $endNum = $_POST['endNum'];
    $findNum = $_POST['findNum'];
    $occur = 0; echo 'from ' . $startNum . ' to ' . $endNum . ' find how many times ' . $findNum . ' occurs';
    echo '<br>';

    $numRange = makeArray($startNum, $endNum); foreach ($numRange as $number){ $test = countOccurrence($number, $findNum);
        echo 'number: ' . $number . ' find: ' . $findNum . ' countOccurrence('.$number.', '.$findNum.'): ' . $test . '<br>'; } echo '<br>'; echo '<p>The digit ' . $findNum . ' occurred ' . $occur . ' times within the range</p>'; echo '<br>'; echo 'countOccurrence(1111, 1) = '; $test = countOccurrence(1111, 1);
    echo $test;
}

इससे प्राप्त होने वाला परिणाम "संख्या: 1 खोज: 1 गणना है (1, 1): 0" इत्यादि।

Im वास्तव में सुनिश्चित नहीं है कि जहां यह गलत हो रहा है क्योंकि यह ठीक से प्रकट होता है जब मैं फ़ंक्शन को मैन्युअल रूप से परीक्षण करता हूं

संपादित करें: यहां मेरा पूरा कोड है

<html lang="en">
    <head>
        <title>Number Counter</title>
        <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    </head>
    <body>
        <div class="container">
            <form id="form" class="form-group" action="" method="post">
                <div class="form-group">
                    <label for="startId">Start Num</label>
                    <input type="number" name="startNum" id="startId" class="form-control">
                </div>

                <div class="form-group">
                    <label for="endId">End Num</label>
                    <input type="number" name="endNum" id="endId" class="form-control">
                </div>

                <div class="form-group">
                    <label for="findId">Find Num</label>
                    <input type="number" name="findNum" id="findId" class="form-control">
                </div>

                <input type="submit" name="submit">
            </form>
        </div>
    <script src="bootstrap/js/jquery-3.5.1.min.js"></script>
    <script src="bootstrap/js/jquery.validate.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script src="validate.js"></script>
    </body>
</html>

<?php

function countOccurrence($number, $digit){ $result = 0;
    while ($number > 0){ $lastDigit = $number % 10; if($lastDigit === $digit){ $result++;
        }
        $number = ($number - $lastDigit)/10; } return $result;
}

function makeArray($startNum, $endNum){
    $numRange = array(); for($ctr = $startNum; $startNum <= $endNum; $startNum++){
        array_push($numRange, $startNum);
    }
    return $numRange; } if (isset($_POST['submit'])){
    $startNum = $_POST['startNum'];
    $endNum = $_POST['endNum'];
    $findNum = $_POST['findNum'];
    $occur = 0; echo 'from ' . $startNum . ' to ' . $endNum . ' find how many times ' . $findNum . ' occurs';
    echo '<br>';

    $numRange = makeArray($startNum, $endNum); foreach ($numRange as $number){ $test = countOccurrence($number, $findNum);
        echo 'number: ' . $number . ' find: ' . $findNum . ' countOccurrence('.$number.', '.$findNum.'): ' . $test . '<br>'; } echo '<br>'; echo '<p>The digit ' . $findNum . ' occurred ' . $occur . ' times within the range</p>'; echo '<br>'; echo 'countOccurrence(1111, 1) = '; $test = countOccurrence(1111, 1);
    echo $test;
}


संपादित करें: उत्तर के लिए धन्यवाद! मैंने अपेक्षित मूल्यों को प्राप्त करने के लिए $ _POST मानों को इस तरह जारी रखने के लिए समाप्त कर दिया

    $startNum = (int) $_POST['startNum'];
    $endNum = (int) $_POST['endNum'];
    $findNum = (int) $_POST['findNum'];

जवाब

SirPilan Aug 18 2020 at 10:04
function countOccurrence($number, $digit){
    $result = 0; while ($number > 0){
        $lastDigit = $number % 10;
        if($lastDigit === $digit){ // <-- bug is here
            $result++; } $number = ($number - $lastDigit)/10;
    }
    return $result;
}

चूंकि आप एक सख्त तुलना कर रहे हैं, ये मूल्य कभी भी समान नहीं हैं। यहाँ क्यों है:

जब आप $ _POST से डेटा प्राप्त करते हैं तो यह हमेशा एक स्ट्रिंग होता है। तो आप कॉल कर रहे हैं countOccurrence(1111, '1')जो 0 पर लौटेगा :)

जैसा कि मैंने टिप्पणियों में बताया है, आप अपने कार्यों को इनसे बदल सकते हैं:

  • substr_count के बजाय countOccurrence
  • range के बजाय makeArray

मामले में आप अपने कार्यों के लिए रहना चाहते हैं। अपने इनपुट को इंटवल के साथ अपने फ़ंक्शन में पास करने से पहले एक इंट में कन्वर्ट करें ।

अतिरिक्त जानकारी

ताकि भविष्य में ऐसा होने से रोका जा सके। इस पोस्ट पर एक नजर । इसकी php की एक अपेक्षाकृत नई विशेषता है, जिसे इस प्रकार के परिदृश्यों के लिए पेश किया गया था ।

TimBrownlaw Aug 18 2020 at 10:10

यह वह जगह है जहाँ आपका छोटा बगबर है ...

if($lastDigit === $digit){

आप यहाँ जो अपेक्षा कर रहे हैं वह मूल्य और प्रकार (===) से तुलना है

आप इसे gettype () का उपयोग करके सत्यापित कर सकते हैं;

while ($number > 0) { $lastDigit = $number % 10; echo '$lastDigit is a '.gettype($lastDigit); echo ' $digit is a '.gettype($digit); echo '<br>'; if ($lastDigit === $digit) { $result++;
    }
    $number = ($number - $lastDigit) / 10;
}

एक POST से मूल्य अपरिवर्तनीय रूप से स्ट्रिंग के होते हैं। अतः $ अंक एक स्ट्रिंग है और $ lastDigit एक संख्या (पूर्णांक) है। === का उपयोग करना विफल हो जाएगा क्योंकि वे एक ही प्रकार के नहीं हैं।

इसलिए जैसा कि PHP में टाइपकास्ट करने की क्षमता है ... === को बदलकर == काम करेगा। अर्थात

if ($lastDigit == $digit) {

PHP RHS मान को LHS प्रकार में बदलने का प्रयास करेगी और फिर तुलना करेगी।

तो अब आप केवल तुलना कर रहे हैं और PHP $ अंक को पूर्णांक में परिवर्तित कर रहा है।

एक सुरक्षित तरीका कास्टिंग को मजबूर करना है। तो आप एक स्ट्रिंग से एक पूर्णांक तक $ अंक डाल सकते हैं, और अपने मौजूदा कोड का उपयोग कर सकते हैं।

function countOccurrence($number, $digit) { $result = 0;

    $digit = intval($digit); // Force $digit to be an integer while ($number > 0) {
        $lastDigit = $number % 10;
        echo '$lastDigit is a '.gettype($lastDigit);
        echo ' $digit is a '.gettype($digit);
        echo '<br>';
        if ($lastDigit === $digit) {
            $result++; } $number = ($number - $lastDigit) / 10;

        echo ' $number is a '.gettype($number);
    }

    return $result;
}

तो इससे सबक, === का उपयोग करते समय, सुनिश्चित करें कि आपके प्रकार भी समान हैं।