查看完整版本: 最小連比?(已解決)
頁: [1] 2

weirdococo 發表於 2017-6-4 03:03 PM

最小連比?(已解決)

本帖最後由 weirdococo 於 2017-6-4 10:52 PM 編輯

作業題目是這樣,輸入一個用逗號分隔的連比,取之最小連比,
譬如輸入8 , 28 , 64 , -128 , -256,輸出為2, 7, 16, -32, -64。
我的一貫作風,先用script language 先寫一遍
use v6;
my Int constant  @data = prompt("input continue ratio\n").split(',').grep(/\d/).map({ $_.Int });
say  @data «/» @data unless @data <= 0 ;,執行結果


然後想說怎麼用純C語言寫出來,目前不知道怎麼用C語言(不是C++)寫出folder/reduce 或是
zip還有可延伸的list,一般是怎麼處理的??



補充內容 (2017-6-4 03:06 PM):
雖然不是作業內容但是也想問用C++一般是怎麼處理的?我是自己寫個zip或reduce和hyper operator。

補充內容 (2017-6-4 03:22 PM):
題外話,最小連比的英文是甚麼阿?

補充內容 (2017-6-4 03:34 PM):
其實我很想知道,道地的C/C++語言起家的人,會用甚麼想法(演算)來解決這個問題,並增加自己的思考方法。

補充內容 (2017-6-4 05:16 PM):
題外話2,其實現在perl的型態很硬,兩個string不能相加,所以一樣要轉型!...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

coal511464 發表於 2017-6-4 07:47 PM

語言只是實現演算法的工具 並不會有什麼太特殊的地方
只是根據資料怎麼處理 寫法會有不同

weirdococo 發表於 2017-6-4 08:14 PM

本帖最後由 weirdococo 於 2017-6-4 08:29 PM 編輯

coal511464 發表於 2017-6-4 07:47 PM static/image/common/back.gif
語言只是實現演算法的工具 並不會有什麼太特殊的地方
只是根據資料怎麼處理 寫法會有不同 ...
題外話,學了一個語言,會碰到不同東西,然後會見到不同演算法,就像是我只用C語言的話,我就不會知道lamda function的意義,因為C語言不鼓勵,也就是說語言會影響演算法,進而引想我的思維,然而我的思維有被一些非主流語言控制住的嫌疑,所以我會想看看主流的作法。
單然我可以用C++語言把上面的寫法照樣刻上去(因該要用到boost),但是要用C有一點困難,也就是說我被一寫思維困住,現在還慢慢再想解決的方法。

補充內容 (2017-6-4 08:16 PM):
還有作業真的是要求用C語言寫,也就是說我真的寫不出來。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

ren1244 發表於 2017-6-4 08:58 PM

我覺得這是好事情,經過這樣的練習才程式語言的背後幫我們做了甚麼事情。
prompt、split、grep、map、…
這些東西必須自己來實現
(不過一開始還是簡單些,先滿足此題需求就好,不求那麼泛用)

想一下C語言的基本型態
最接近 list 的應該是 array
而我們可以用動態宣告來達成可變長度的 array
如果裝滿了,那麼我們必須重新要一塊更大空間的記憶體
再把原本的資料 copy 過去
並釋放舊有的空間

你現在需要訓練的是類似這樣低階的思維
如果依賴外部的函式庫
那麼還是一樣無法感受到寫C語言的感覺
只是把一切你熟悉的東西換個名字罷了

我想先從簡單的開始吧:
1. 用scanf 輸入字串
2. 將字串解析成整數陣列
3. 寫一個函數,可以將整數陣列約分到不能再約分

先完成這些,再來想可變長度陣列的事情
此外,若要實作 regex 應該不是那麼簡單可以完成的。

補充內容 (2017-6-4 09:05 PM):
也可以想想:C++ STL 中,vector 跟 list 的差別是甚麼?插入、移除、存取第N個元素,分別是哪一種效率高?
函式的差別,不只是他給予的介面。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

caoh 發表於 2017-6-4 09:07 PM

人換個情景、語言,寫不出來事很正常的。
你只是需要練習 C 的撰寫方式,不是非得函數式的思維,畢竟 C 不擅長。
更何況要做出 zip, map, fold 難道不能自己刻嗎?
只是 C 不擅長函數組合的模式,硬要寫比較憋扭吧
C 必有其長處,否則早被淘汰了
  
  
  <br><br><br><br><br><div></div>

weirdococo 發表於 2017-6-4 09:52 PM

本帖最後由 weirdococo 於 2017-6-4 10:23 PM 編輯

ren1244 發表於 2017-6-4 08:58 PM static/image/common/back.gif
我覺得這是好事情,經過這樣的練習才程式語言的背後幫我們做了甚麼事情。
prompt、split、grep、map、…
這 ...
3. 寫一個函數,可以將整數陣列約分到不能再約分
就是這個想不出來,如果有限時解題的話,我一定自己刻一個fold/reduce去寫,
還沒想透,可能用兩個loop再加一個變數去完成fold的感覺,但是我在想這樣對嗎?
感覺像這樣
int64_t gcd ( int64_t a, int64_t b ) {
  int64_t c;
  while ( a != 0 ) {
     c = a; a = b%a;  b = c;
  }
  return b;
}

int64 buffer = array;
while( true ) {
//會有指標退化的問題  不能作為sub
    if (buffer == 1 )
        break;
    for(uint64_t i =1; i <= sizeof(array); i++) {
        buffer  = gcd( array,buffer  );
    }
    for(uint64_t i =1; i <= sizeof(array); i++) {
        array = array/ buffer ;
    }
   
}


補充內容 (2017-6-4 10:08 PM):
vector 跟 list 的差別老師有考! 幾本上就是記憶體連不連續讓我有沒有辦法指定第N個元素,list 沒辦法,所以他只能都跑一遍。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

weirdococo 發表於 2017-6-4 10:05 PM

caoh 發表於 2017-6-4 09:07 PM static/image/common/back.gif
人換個情景、語言,寫不出來事很正常的。
你只是需要練習 C 的撰寫方式,不是非得函數式的思維,畢竟 C 不 ...

就是想不出非得函數式的思維{:9:},所以當我的資料是一個連續的sequence的時候就想不出來了!
像是這題,我寫不出來不用fold概念的'將整數陣列約分到不能再約分'的function!...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

weirdococo 發表於 2017-6-4 10:49 PM

weirdococo 發表於 2017-6-4 10:05 PM static/image/common/back.gif
就是想不出非得函數式的思維,所以當我的資料是一個連續的sequence的時候就想不出來了!
像是這題, ...

找到問題了,我發覺我perl也錯了,不需要那個while。
所以就perl因該是這樣,
my Int constant  @data = prompt("input continue ratio\n").split(',').grep(/\d/).map({ $_.Int });
say  @data «/» @data;
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2017-6-4 10:50 PM

本帖最後由 chevylin0802 於 2017-6-5 11:12 AM 編輯

weirdococo 發表於 2017-6-4 10:05 PM
就是想不出非得函數式的思維,所以當我的資料是一個連續的sequence的時候就想不出來了!
像是這題, ...
先將8拆分
可以得到1,2,4,8
拆分方式你應該會
反正就是用for迴圈找出來
1不用算
然後由高而低作為除數
依次帶進去其他數字取餘數
只要一個不能整除,也就是餘數不為零
就換下一個數字當除數
找出最大公因數之後
就不必再帶下一個數字去當除數
而是每一個輸入的數字去除這個最大公因數
這就是演算法
演算法其實非常重要
資料結構一半以上的核心都在這個部份#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int input_array[] = { 8 , 28 , 64 , -128 , -256 };
int output_array;
int parts;

int main(int argc, char** argv)
{

        int i, j, k;
        int flag;

        /* 求出8的因數 */
        for (i=2, j=0; i < input_array/2 ; i++) {
                if (input_array % i == 0) {
                        parts = i;
                        j++;
                }
        }
        /* 8本身也可以被自己整除 */
        parts = input_array;

        /* 除數陣列的迴圈, 數值從高而低 */
        for (i = j; i >= 0; i--) {
                for(k = 1; k < 5; k++) {
                        if( input_array % parts != 0) {
                                /* 不能被整除時, 跳出內層迴圈 */
                                flag = 0;
                                break;
                        } else {
                                /* 能被整除時, 將input_array整除之後寫到output_array裏 */
                                flag = 1;
                                output_array = input_array/parts;
                        }
                }
                /* 所有input_array的迴圈都可以被整除時, 表示已找到最大公因數 */
                if(flag == 1) {
                        /* 由於8沒有進行迴圈整除測試, 所以在此補上整除後的結果寫到output_array裏 */
                        output_array = input_array/parts;
                        /* 跳出外層迴圈 */
                        break;
                }
        } /* for (i = j; i >=0; i--) */

        print_f("Outputs : ");
        for (i = 0; i < 5; i++) {
                print_f(" %d,", output_array);
        }
        print_f("\n");

        exit(0);
}
這是範例程式, 已測試!...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

weirdococo 發表於 2017-6-4 11:58 PM

本帖最後由 weirdococo 於 2017-6-4 11:59 PM 編輯

chevylin0802 發表於 2017-6-4 10:50 PM static/image/common/back.gif
先將8拆分
可以得到1,2,4,8
拆分方式你應該會

這感覺是一個較少花費的解決方案,我對演算法的概念是如何更有效率做出解果,
通常不直觀,其實我有想過找本演算法來看,但後來還是作罷,
因為我才大一學了一學期的程式設計,一般來說演算法是大三大四的課程,
也就是說我有很多依賴還沒學好,再者程式就算不走最短路徑也會有結果,
也就是說還沒有優化的打算,這也是我可以接受script language這種慢速的東西的原因,
就算我學了演算法寫程式,如果不是遇到效率問題,我想我也會到最後才把沒
有效率的地方改寫吧。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

weirdococo 發表於 2017-6-5 12:04 AM

weirdococo 發表於 2017-6-4 10:49 PM static/image/common/back.gif
找到問題了,我發覺我perl也錯了,不需要那個while。
所以就perl因該是這樣, ...

問題已解{:31:}
找機會再用python寫寫看,題外話,最近python也能定型(Type Hints),好像越來越少Duck typing的程式語言了。

chevylin0802 發表於 2017-6-5 12:31 AM

本帖最後由 chevylin0802 於 2017-6-6 08:30 AM 編輯

weirdococo 發表於 2017-6-4 11:58 PM
這感覺是一個較少花費的解決方案,我對演算法的概念是如何更有效率做出解果,
通常不直觀,其實我有想過找 ...
不對,演算法的基礎就是資料結構
資料結構一般都是大一下學期的必修課程
沒道理改到大三才學
演算法確實不太直觀
但是它卻是有必要性

另外一點
script language腳本語言
跟直譯式程式語言還是有差別的
腳本語言只能算是直譯式語言的子集
但不能視為相同

事實上
只要是程序導向的程式語言
當有人根據它做出直譯器時
都可以稱它叫做直譯式程式語言
哪怕是C或者是Pascal
PC版最早的Basic就是直譯式語言
但是它並不能稱為腳本語言

然而為何直譯式程式語言在現在卻是越來越普及
其實最主要的兩大原因所導致
第一個原因是現在的電腦的速度越來越快
已經足夠擔負起直譯式語言的執行效率差的問題
而第二個原因則是比如C/C++的程式
常常因為人為疏失而導致記億體的配置與釋放動作不完整
造成已配置的記憶體經常在程式結束之後仍然不得釋出
這也就導致現在越來越多工程師喜歡使用例如Python之類的程式語言來開發
因為直譯式程式語言自行管理著記億體的配置
可以確保不發生memory leak的問題

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a333221 發表於 2017-6-5 10:55 PM

chevylin0802 發表於 2017-6-4 10:50 PM static/image/common/back.gif
先將8拆分
可以得到1,2,4,8
拆分方式你應該會


大大,人家的 8 , 28 , 64 , -128 , -256 只是舉例,要的是一般情況也能處理,

可是你 sample 用的方法似乎只針對  8 , 28 , 64 , -128 , -256 這例子在做,

沒就一般情況進行處理...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2017-6-6 05:39 AM

本帖最後由 chevylin0802 於 2017-6-6 05:48 AM 編輯

a333221 發表於 2017-6-5 10:55 PM
大大,人家的 8 , 28 , 64 , -128 , -256 只是舉例,要的是一般情況也能處理,

可是你 sample 用的方法 ...

那是他的作業,我不可能給他完整版的程式。
所以只給一個sample。
至於他如果要手動輸入數值
他就要自己去改
演算法都有給他了
剩下來的事應該由他自己去做
至於如果他的數值個數要可變動
那就再用link list的方式做
C的link list網路上一堆範例
總不需要我再提供吧?
反正就是做一個struct而已
再加上幾個function
比如,size,add,remove,next, head,tail,等自己動手做...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a333221 發表於 2017-6-6 11:18 PM

本帖最後由 a333221 於 2017-6-6 11:34 PM 編輯

chevylin0802 發表於 2017-6-6 05:39 AM static/image/common/back.gif
那是他的作業,我不可能給他完整版的程式。
所以只給一個sample。
至於他如果要手動輸入數值

作業當然是自己做。
昨天沒看仔細,誤以為大大直接假設已知 8 的所有非 1 因數為 2 4 8,
所以誤認為大大的演算法只針對題目給的例子在做。

大大 8 的所有因數是讓程式自己算的,這演算法一定會比原發問者的來得有效率嗎?
還有,要算因數,要講究演算法的話,迴圈的終止條件要用開根號,用迴圈算出一半的因數,
另一半用除的得出。大大用的是除以 2,除以 2 可以用一個迴圈完成,但運算量會多不少。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>
頁: [1] 2