2016-10-02 3 views
1

먼저,이 학습은 프로그래밍 학습을 시작할 때 학교에서받는 연습 중 하나와 같습니다. Weeeeell 그것이 그 이상인 것으로 판명되었습니다.어려운 해결책으로 쉬운 운동 C++

주요 운동은 누구나 풀 수있는, 매우 간단하다 :

편집 : 나는 원래 (번역) 문의 보류 가지고 :

쓰기 하나 개의 인수를 가지고 재귀의 기능에 대한 두 가지 구현을 (n = 9 자리의 자연수) n의 첫 번째 숫자를 숫자의 끝으로 재배치하여 얻은 숫자를 반환합니다. 예를 들어, n이 4273이면 함수는 2734를 반환해야합니다. C1) 루프를 사용할 수 있습니다. C2) 루프를 사용할 수 없습니다.

고지, 처음 쉽습니다.

long function(long n) 
    { 
     long newNumber = 0, p = 1; 

     while(n>9) 
     { 
      newNumber = n%10 * p + newNumber; 
      n = n/10; 
      p = p*10; 
     } 

     return newNumber*10+n; 
    } 

이제는 어떤 종류의 루프도 사용하지 않고 동일한 작업을 수행합니다. 아니, 잠시 동안, 등등. 당신은 얼마나 오랫동안인지 모르겠다. 3 자리 숫자일지도 모르겠다. 9 일 수도있다. 또한 모든 일은 오직 하나의 기능만으로 이루어져야한다.

지금, 물론, 하나 개의 간단한 솔루션, 그리고 끔찍한 일이

if(n<100) 
     return n%10*10+n/10; 
    else 
     if(n<1000) 
      return n%100*10+n/100; 
     else 
      if... 
    ... 
    ... 
    ... 

같은 것을 작성하는 것입니다 그러나 그것은 코드의 가장 바람직한 부분이 아니다. 이 일을하는 다른 깨끗한 방법이 있습니까? 지금까지 아무도 내가 물어 본 사람이 없습니다.

다른 점이 있습니다. 이것은 초심자가 해결할 수있는 것으로 생각됩니다. (내 친구가 그의 운동 중 하나를 해결하는 것을 돕는 동안 이것을 보았습니다.) 그래서 초보자가 결코 알 수없는 멋진 라이브러리를 사용하면 올바른 해결책이 될 수 없습니다. 나는 모든 아이디어에 대해 궁금해.) | 로그 (N) |

:

또한, 나는 당신이 수는 수식을 사용하여이 자리의 번호를 찾을 수 있다는 사실을 알고

long function(long n) 
    { 
      int k; // number of digits of n 

      k = (int) (ln(n)/ln(10)) + 1; // applying the formula 
      long p = pow(10, k-1); 
      return n%p * 10 + n/p; 
    } 

을하지만 고등학교에있는 동안 내가 C++에서 LN 기능에 대해 배운 기억하지 않는 다음과 같이 C++에서 사용할 수 + 1 = LN (N)/LN (10) + 1 그들도 마찬가지였다. 그래서 ... 이렇게하는 초보자 친화적 인 방법이 있습니까? 제약

목록 :

  • 하나의 함수
  • 없음
  • 의해 형성된 수를 반환한다 (최대 9 자리 숫자)를 숫자 형태로 단지 1 파라미터를 수신하는 루프 첫 번째 숫자를 숫자 끝으로 재배치
  • 문자열 없음 (합법적 인 솔루션 임에도 불구하고)

편집 : 그럼으로 나는이 문제를 제안한 해결책이 대수학을 사용하는 해결책이라고 들었습니다 ..... 그 학생은 결코 C++에서 그것을 사용하지 않았기 때문에 어느 것이 이상합니다. 제 추측으로 그들은 성명서에 엿 먹었고, 그것은 그들의 "구원 변명"입니다.

+2

재귀 함수를 사용한다고 생각하십니까? –

+0

표준 라이브러리 함수를 호출 할 수 있습니까? –

+2

번호를 사용해야합니까? 이것은 문자열로 사소한 것입니다. – user4581301

답변

3

다음은 std :: log10 및 std :: pow (#include <cmath> 필요)를 사용하는 하나의 솔루션입니다.

long func(long in) { 
    long base = std::pow(10, (int)std::log10(in)); 
    long left_most_num = in/base; 
    long body = in - left_most_num * base; 
    return body * 10 + left_most_num; 
} 
+0

이 문장은 그 문장에서 기대했던 것과 가장 근접한 문장이므로 (나는 들었습니다), 이것을 받아 들인 해결책으로 표시하고 있습니다. 그러나이 문제에서 다소 제약을 따르는 창조적 인 해결책이 많이 있습니다 실. –

+0

@Bob__ 당신은 절대적으로 옳고, 업데이트 중입니다 ... – iamai

1

recursion을 사용하십시오.

long f(long n, long base) 
{ 
    if(n <= 9) 
     return n; // last 'iteration' 
    else 
     return (base * (n % 10)) + f(n/10, 10 * base); 
} 

.... 
f(1234, 10); 
+0

이 시점에서 함수는 더 이상 OP에서 제공 한 것과 같은 수의 인수를 갖지 않으므로이 함수가 솔루션으로 간주되는지 여부는 의심 스럽습니다. –

+0

@FrerichRaabe - 좋은 지적이지만 쉽게 고치기 - 하나의 변수만으로 외부 함수로 래핑하십시오. – bavaza

+0

OP는 '전체 작업은 하나의 기능 만 수행해야합니다.'라고 썼습니다. –

0

편집 1 : 루프를 사용하지 않도록 변경 다음은 몇 가지 테스트되지 않은 코드입니다. 편집 2 :이 솔루션은 더 이상 OP가 설정 한 요구 사항을 충족하지 않습니다. 그러나 나는 해결책에 문자열을 사용할 수있는이 문제가있는 앞으로의 독자를 위해 나의 대답을 남겨 둘 것입니다.

#include <iostream> 
#include <string> 

int main() { 
    long testNum = 0; 
    long newNum; 
    std::cout << "Enter a number: "; 
    std::cin >> testNum; 

    std::string stringFromLong; 

    stringFromLong = std::to_string(testNum); 
    char tempChar = stringFromLong[0]; 

    std::string newString = stringFromLong.substr(1, stringFromLong.length() - 1) + tempChar; 

    newNum = std::stol(newString); 
    std::cout << newNum << std::endl; 
    return 0; 
} 

이것은 숫자를 가져 와서 문자열로 변환합니다. 문자열 변수의 첫 문자를 임시 변수로 유지합니다. 새로운 문자열은 우리의 원래 문자열 (두 번째 문자에서 시작하여 마지막 문자로 이동)과 마지막에 넣은 임시 문자로 구성됩니다. 그런 다음 std::stol()을 사용하여 우리의 문자열을 출력용 long으로 변환합니다.

+1

질문을 읽었습니까? 루프가 없습니다. – deviantfan

+0

나는 그것을 읽었다. 조금 실망했다. 업데이트 될 것이다. – Gavin

+0

만약 당신이 할 일이'cin'이고'cout'은 숫자 일 것인데, 왜 그 번호를 전혀 신경 쓰지 않을까요? 전체적인 방법으로 문자열을 유지하십시오. 즉, 문자열의 내용이 숫자라는 것을 어떻게 알 수 있습니까? 하지만 어쨌든 그 문제가 있습니다. 체크되지 않은 입력을 사용하는 정의되지 않은 동작을 방지하려면'if (std :: cin >> testNum)'을 추천하십시오. – user4581301

1

문자열을 사용하도록 허용 된 경우 이와 같은 작업을 수행 할 수 있습니다. 기본적으로 문자열을 사용하여 숫자를 벡터로 처리하므로이 작업이 간단합니다.

현재로서는 이것이 허용되지 않습니다 (이 솔루션을 테스트 할 때 &을 쓰는 동안 보지 못했던 질문에 대한 편집 # 3). 그러나 누군가가 미래에이 질문에 직접적으로 관련 될 경우를 대비하여 여기에 올릴 것이며 문자열을 사용하지 않는 것에 국한되지 않습니다.

#include <string> 
#include <cstdlib> 

long firstDigitToEnd(long n) { 
    bool neg = (n < 0);     // Preserve signed-ness. 
    if (neg) { n = labs(n); }   // Obtain absolute value, for convenience. 

    std::string num = std::to_string(n); // Convert number to string. 

    char first = num[0];     // Obtain first digit. 
    num.erase(0, 1);      // Erase first digit, shift rest forwards. 
    num.push_back(first);    // Append first digit to end. 

    // And we're done. Convert string back to number, restore signed-ness. 
    return (neg ? -(std::stol(num)) : std::stol(num)); 
} 

// ----- 

// Testing code. 

#include <iostream> 
#include <limits> 

void readCin(long& l); 

int main() { 
    long n = 0; 

    do { 
     if (n) { 
      std::cout << "Result: " << firstDigitToEnd(n) << std::endl; 
     } 

     std::cout << "Input number, or 0 to exit: "; 
     readCin(n); 
    } while (n); 

    std::cout << "...And we're gone." << std::endl; 
} 

// Read a number, or clear the buffer if non-number is entered. 
void readCin(long& l) { 
    using std::cin; 

    cin >> l; 
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

    if (cin.fail()) { 
     cin.clear(); 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
     l = 0; 
    } 
} 

실사 : here에서 확인하십시오.

0

컴파일 타임에 INT_MAX를 알아야한다는 제약 때문에,보기 흉한 경우는 간단합니다.

if(x > 999999999) 
    ndigits = 9; 
else if(x > 99999999) 
    ndigits = 8; 

등; 그러면 ndigits와 곱셈을 사용할 수 있습니다. 나누기 및 모듈러스를 사용하면 원하는 결과를 얻을 수 있습니다.

그러나 x가 제한되지 않으면 본질적으로 어떤 형태의 루프를 사용하지 않고 크기를 알 수있는 방법이 없습니다.

관련 문제