直方圖內矩形面積

輸入一組直方圖數據,其中每列的寬度爲1,求所給直方圖包含的最各個高度的矩形面積。比如,對於直方圖[2,7,9,4,1],它所包含的各個高度矩形的面積爲8,14,9,12,5
給定一個直方圖及它的總寬度返回相應面積。

  • 方法一:
    方法一的思路是,從前完後遍歷直方圖,在相應的位置往前後搜索,遇到直方圖高度更低的則停止,通過左右的界限來求其寬度。(方法一代碼值考慮了值爲0到9的情況)
#include <iostream>
using namespace std;
int main()
{
    cout<<"cin a histogram and the length n:";
    cout<<"such as [2,7,9,4,1],5"<<endl;
    string strin;
    getline(cin,strin);
    int last=strin.length()-1;
    int n=int(strin[last]-'0');
    int his[n+1];
    his[n]=0; 
    n=0;
    int sqr[n];
    for(int i=0;i<strin.length()-1;i++)
    {
        if(strin[i]<='9'&&strin[i]>='0')
        {
            his[n]=strin[i]-'0';
            n++;
        }
    }
    for(int i=0;i<n;i++)
    {
        int l=i,r=i;
        //往左搜索
        while(his[i]<=his[l] && l>=0)
        {
            l--;
        }
        //往右搜索
        while(his[i]<=his[r] && r<=n)
        {
            r++;
        }
        sqr[i]=(r-l-1)*his[i];
        cout<<his[i]<<' '<<sqr[i]<<endl;
    }
    return 1;
}
  • 方法二:
    方法二思路是:從左到右遍歷直方圖,定義一個棧,首先將直方圖中第一個高度的序號入棧,往後搜索直方圖,每次把棧頂元素對應的高度與當前搜索到的高度進行比較,如果當前高度高於棧頂元素,說明可以往下擴展,那麼將當前高度的序號入棧。而如果當前高度低於棧頂元素對應直方圖中高度,那麼先求棧頂元素對應高度的矩形面積,由於當前高度低於棧頂元素高度,而棧頂元素的下一個元素對應的高度也是低於棧頂元素的(該元素是棧頂元素往左搜索的第一個高度更小的元素),因而,可以通過相應序號得到寬度。計算完該高度的矩形面積後,將棧頂元素出棧,繼續比較新的棧頂元素對應高度與當前元素對應高度,仍然是棧頂元素對應高度更高,那麼繼續求其對應高度的矩形面積,依次循環。直到棧頂元素高度低於當前元素高度時入棧,繼續往下。
    此處的小技巧是,把直方圖第一個元素前一位和最後一個元素後一位高度都設置爲0,這樣方便求第一個和最後一個序號對應的直方圖。且壓入棧的的方柱的索引而不是高度,因爲這樣方便計算橫向距離。
#include <iostream>
#include <stack>
using namespace std;
int main()
{
    string str;
    stack<int> hisstack;
    getline(cin,str);
    int* his=new int;
    int* sqr=new int;
    int n=1;
    for(int i=0;i<str.length();i++)
    {
        if(str[i]>='0'&& str[i]<='9')
        {
            his[n]=str[i]-'0';
            while(str[i+1]>='0'&& str[i+1]<='9')
            {
                his[n]=his[n]*10+int(str[i+1]-'0');
                i++;
            }
            n++;
        }
    }
    int num=his[n-1];
    his[n-1]=0; //把直方圖之後一個高度設置爲0 
    his[0]=0;  //把直方圖之前一個高度設置爲0 
    hisstack.push(0);          
    int hei=0;
    int wid=0;
    int curindex;
    for(int i=1;i<=num+1;i++)      
    {
        if(his[i]>=his[hisstack.top()])
        {
            hisstack.push(i);//將相應的編號入棧,方便求其橫向差值
        }
        else
        { 
          while(his[i]<his[hisstack.top()])
          {
            hei=his[hisstack.top()];
            curindex=hisstack.top();
            hisstack.pop();
            wid=i-1-hisstack.top();
            sqr[curindex]=hei*wid;
          }
          hisstack.push(i);
        }   
    }
    for(int i=1;i<=num;i++)
    {
        cout<<his[i]<<' '<<sqr[i]<<endl;
    }
    return 1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章